5.2.24 · D1 · Coding › C++ Programming › Concurrency — std - thread, std - mutex, std - lock_guard, s
Ek thread ek doosra worker hai jo tumhara code pehle worker ke saath saath run karta hai; ek mutex ek aisi single key hai jise sirf ek hi worker hold kar sakta hai, taaki dono kabhi bhi ek hi memory par ek saath likhne ki koshish na karein. Parent page par jo bhi hai woh sirf is baat ka tarika hai ki us key ko safely kaise pass karein taaki koi use drop na kare ya us par ladte na rahein.
Parent note padhne se pehle, tumhe har word aur symbol ka matlab dekhna hoga. Hum inhe ek-ek karke, neeche se upar tak, build karte hain. Neeche jo bhi hai woh koi aisa term use nahi karta jo pehle draw nahi hua.
Definition Instruction & program counter
Ek program chhoti-chhoti steps ki ek list hoti hai (instructions). Computer ek ungli — jise program counter kehte hain — "us step par pointing" rakhta hai jo abhi ho rahi hai. Har step ke baad, ungli ek line neeche move karti hai.
Picture: ek to-do list jisme ek ungli current line par point kar rahi hai.
Ek thread ek aisi chalti hui ungli hai jo code ke through walk karti hai. Ek normal program mein ek ungli hoti hai. Concurrency ka matlab hai ek hi moment mein do ya zyada ungliyan code ke through step kar rahi hain.
Figure dekho: left column ek thread hai (ek ungli), right mein ek doosri ungli independently move kar rahi hai. Dono memory ke same boxes ko read aur write kar sakti hain — wahin se musibat shuru hoti hai.
Intuition Is topic ko yeh kyun chahiye
"Ek ungli jo ek list par chal rahi hai" ka idea na ho, toh thread aur ek hi waqt mein shabd ka koi picture hi nahi hai. Baad ki har problem (races, locks) bas "do ungliyan ek hi box ke liye pahunch rahi hain" hai.
Ek core CPU ke andar ek physical worker hai jo ek waqt mein ek ungli move kar sakta hai. Ek 4-core chip genuinely 4 ungliyan simultaneously run kar sakta hai.
Yeh topic kyun mention karta hai: parent kehta hai concurrency exist karti hai kyunki cores idle baithte hain . Ek ungli ek core use karti hai; baaki cores kuch nahi karte. Ek doosri thread ek doosre core ko kaam par lagati hai → zyada steps per second hoti hain (throughput ).
Definition Variable = memory mein ek labelled box
counter jaisa ek variable ek box hai jisme ek number hota hai. Use read karna number ko bahar copy karta hai; use write karna ek naya number andar dalta hai.
Shared memory ka matlab hai: wahi box dono ungliyon ko visible hai. Yeh powerful (cooperation) bhi hai aur dangerous (collision) bhi, jo agli section ko motivate karta hai.
Parent claim karta hai ++counter ek action nahi balki teen hai. Yeh raha woh picture jo ise prove karta hai.
Intuition Yeh kyun matter karta hai
Kyunki yeh teen steps hain, ek doosri ungli beech mein slip kar sakti hai. Figure mein, dono ungliyan 5 read karti hain, dono 6 compute karti hain, dono 6 likhti hain — do increments hue lekin box sirf ek se badha. Ek increment kho gayi. Woh khoyi hui step hi data race hai.
Ek data race yeh hai: do threads same box ko touch karti hain, kam se kam ek likhti hai , aur unhe order karne ka koi rule nahi hai. C++ mein yeh undefined behavior hai — program ko kuch bhi karne ki ijazat hai.
Recall "Kam se kam ek likhta hai" kyun?
Do ungliyan sirf ek hi box ko read kar rahi hain toh kabhi conflict nahi hota — reading se woh change nahi hota. Khatre wali baat tab hai jab ek finger read ya write kar rahi ho aur doosra write ho raha ho. ::: Kyunki ek write box ko beech mein change kar deta hai, isliye doosri ungli jo dekhti hai woh luck (timing) par depend karta hai.
Link: yeh exactly Undefined behavior in C++ hai — compiler assume karta hai yeh kabhi nahi hota, isliye observed result bakwaas ho sakta hai, sirf "kabhi-kabhi galat" nahi.
Accesses ko serialize karna matlab hai: unhe single-file line mein force karo, ek ungli apna pura read-modify-write khatam kare pehle agle ki baari aaye. Koi overlap nahi → koi khoyi hui step nahi.
Ek mutex (agla) ka poora point yahi hai ki ek chosen region ko serialized banao.
Definition Mutex (mutual exclusion)
Ek mutex ek single key hai. Do actions:
lock() — "key uthao". Agar koi aur hold kar raha hai, tum wait karte ho (block) darwaze par.
unlock() — "key wapas rakho", kisi waiter ko andar aane do.
Kyunki exactly ek key hai, exactly ek ungli ek waqt mein guarded room ke andar ho sakti hai.
Figure mein key dono ungliyon ko ek queue mein force karti hai: finger A key hold karti hai aur apna pura read-modify-write karta hai; finger B darwaze par atki rehti hai jab tak A key return nahi kar deta. Race gone.
Block hone ka matlab hai ek thread pause ho jaati hai aur kuch nahi karti , cheaply, jab tak woh cheez (key) jiske liye wait kar rahi hai available na ho jaaye. Yeh "busy spinning" nahi hai; OS use park kar deta hai.
lock_guard samajh mein aane se pehle, tumhe scope dekhna hoga.
Ek scope ek { aur uske matching } ke beech ka region hai. Jab ungli closing } cross karti hai, andar bane har object ko destroy kar diya jaata hai, reverse order mein — guaranteed , chahe hum jaldi nikal jayein ya exception throw ho.
Definition Constructor / Destructor
Ek constructor jab object janam leta hai tab run hota hai (uski declaration par).
Ek destructor jab object marta hai tab run hota hai (closing } par).
Key insight: tum destructor skip nahi kar sakte. return, break, ya exception se nikalna bhi ise run karta hai.
Yeh guaranteed-cleanup rule RAII and resource management ki poori foundation hai — "constructor mein resource lo, destructor mein release karo".
std::lock_guard<std::mutex>
Ek chhota sa object jiska constructor lock() call karta hai aur destructor unlock() call karta hai . Tum bas ise declare karo; key uth jaati hai aur — guaranteed destructor ki wajah se — } par hamesha wapas rakh di jaati hai. Iske paas koi doosra button nahi hai.
std::unique_lock<std::mutex>
Wohi RAII idea lekin extra buttons ke saath: jaldi unlock karo, late lock karo (defer_lock), re-lock karo, aur move ho sako. Ise tabhi use karo jab tumhe in buttons mein se koi chahiye — warna lock_guard simpler aur cheaper hai. std::condition_variable ke liye yeh required hai.
<std::mutex> ko scary syntax samajhna
< > bas kehta hai "ek lock_guard for a std::mutex" — fill in karo ki woh kaunsi key guard kar raha hai. Yeh ek template parameter hai, maths nahi. :::
std:: aur ::
std ek namespace hai — standard library mein ek labelled drawer. std::thread padhne ka matlab hai "the thread tool from the std drawer". :: bas "andar pahuncho" hai.
Program counter = a moving finger
Variable = a box in memory
Read modify write = 3 steps
Scope and destructor = guaranteed cleanup
lock_guard and unique_lock
Har row apne neeche waale ko feed karti hai. Jab tak tum lock_guard tak pahunchte ho, har pehla word already ek picture rakhta hai.
Khud ko test karo — tum parent note ke liye ready ho jab tum bina dekhhe har cheez ka jawab de sako.
Thread kya hai, ungli waale picture mein? Instructions ki ek list par step karne waali ek chalti hui ungli; concurrency = ek saath do ya zyada ungliyan.
Ek core tumhe kya deta hai? Doosron ke saath exactly ek ungli (thread) truly simultaneously run karne ki ability.
++counter ek operation kyun nahi balki teen operations hain?Yeh hai box read karo, scratch pad par ek jodo, wapas likho — ek doosri ungli beech mein slip kar sakti hai.
Data race ko teen conditions mein define karo. Same memory box, kam se kam ek writer, unhe order karne wala koi synchronization nahi — jo C++ mein undefined behavior hai.
Ek mutex physically kya model karta hai? Ek single key jo sirf ek ungli hold kar sakti hai; lock() ise uthata hai (hold hone par block karta hai), unlock() return karta hai.
Ek thread ke liye "block" ka matlab kya hai? OS thread ko kuch nahi karte hue park kar deta hai jab tak jis key ka woh wait kar raha hai woh free na ho jaaye.
Destructor kabhi skip kyun nahi ho sakta? Scope ki closing brace cross karna hamesha andar bane objects ko destroy karta hai — jaldi return ya exception par bhi.
lock_guard ka one-line kaam kya hai?Apne constructor mein mutex lock karo, destructor mein unlock karo, taaki key scope exit par hamesha return ho.
Tum unique_lock kab reach karte ho? Jab tumhe extra buttons chahiye — jaldi unlock, deferred lock, move, ya ek condition variable.
Kisi naam se pehle std:: ka matlab kya hai? Woh naam standard library ke std namespace (drawer) mein rehta hai; :: use reach karta hai.