4.2.17 · HinglishOperating Systems

Monitors — condition variables, wait, signal, broadcast

1,862 words8 min readRead in English

4.2.17 · Coding › Operating Systems


WHAT is a Monitor?

Monitors kyun invent kiye? Raw semaphores ke saath, lock acquire/release manually code mein yahan-wahan bikhre hote hain — ek signal() bhul gaye toh deadlock forever. Monitor mutual exclusion ko structural banata hai: compiler/runtime har procedure ke around lock lagaata hai, toh tum use bhul hi nahi sakte. Tum sirf conditions ke baare mein sochte ho, locking ke baare mein nahi.


WHAT is a Condition Variable?


Golden rule: WHY wait ko while ke andar rakhna zaroori hai

Chalte hain derive karte hain kyun while (na ki if) mandatory hai. Maan lo ek consumer count > 0 ke liye wait karta hai:

  1. Consumer wait mein so jaata hai kyunki count == 0 hai. Woh CPU se bahar hai aur lock ke bahar hai.
  2. Producer enter karta hai, count = 1 set karta hai, signal call karta hai. Consumer "ready" state mein aa jaata hai.
  3. Lekin "ready" ≠ "running." Signal aur consumer ke actually lock re-acquire karne ke beech, ek teesri thread sneak in kar sakti hai aur woh item consume kar sakti hai, count = 0 dobara set kar ke.
  4. Consumer finally run karta hai — agar usne if use kiya, toh woh aage badh jaata jaise count > 0 hai, lekin ab woh hai! Bug.

while ke saath, wake-up par consumer predicate dobara test karta hai, use false paata hai, aur wait par wapas loop karta hai. Safe. Yahi spurious wake-ups (kuch OSes bina wajah threads jagaate hain) aur broadcast (bahut jagaaye jaate hain, sirf ek jeetta hai) se bachne ka sahi tarika hai.


HOW wait atomicity achieve karta hai (the crux)


Mesa vs. Hoare semantics — signal ke baad lock KAUN rakhta hai?

Lagbhag saare real systems (Java, pthreads, Python threading.Condition, Go) Mesa use karte hain. Toh practically: hamesha while.

Figure — Monitors — condition variables, wait, signal, broadcast

WORKED EXAMPLE 1 — Bounded Buffer (Producer/Consumer)

monitor BoundedBuffer:
    buf[N], count = 0
    condition notFull, notEmpty
 
    procedure produce(item):
        while (count == N)        # Why? buffer full → can't add. while, not if (Mesa).
            wait(notFull)         # Why? drop lock + sleep until space appears.
        buf.add(item); count++    # Why? safe: we hold the lock, count < N proven.
        signal(notEmpty)          # Why? a consumer may be sleeping on empty buffer.
 
    procedure consume():
        while (count == 0)        # Why? nothing to take → wait.
            wait(notEmpty)
        item = buf.remove(); count--
        signal(notFull)           # Why? we just freed a slot; a producer may wait.

Do CVs kyun? notFull aur notEmpty alag conditions represent karte hain. Agar tum ek CV aur signal use karte, tum producer ko jagaa sakte ho jabki sirf consumer proceed kar sakta tha → woh wapas so jaata, ek wakeup waste hota, shayad deadlock ho jaata. Alag CVs = bilkul sahi group ko jagao.


WORKED EXAMPLE 2 — Jab broadcast USE karna ZAROORI hai

Maan lo ek single CV ready ek resource pool guard karta hai, aur waiting threads ko alag-alag amounts of memory chahiye. Ek thread 10 MB free karta hai.

  • signal(ready) ek thread jagaata hai. Kya hua agar use 100 MB chahiye aur woh proceed nahi kar sakta, lekin doosre waiter ko sirf 5 MB chahiye aur woh kar sakta tha? 5 MB thread soyi rehti hai → wasted wakeup / starvation.
  • broadcast(ready) sabko jagaata hai; har ek apne while mein apna predicate re-test karta hai; jo proceed kar sakte hain karte hain, baaki wapas so jaate hain. Correct.

WORKED EXAMPLE 3 — Lost-signal bug (aur fix)

# BROKEN consumer
if (count == 0)        # ← if, not while
    wait(notEmpty);
take();

Kyun toot-ta hai: Mesa ke under, ek teesra thread signal aur re-acquire ke beech buffer khali kar sakta hai (upar ka derivation). Phir take() empty buffer par run karta hai → crash. Fix: ifwhile kar do. Ek character. Wake ke baad re-test karta hai.


Recall Feynman: ek 12-saal ke bachche ko samjhao

Socho ek kitchen jisme ek time par sirf ek cook fit ho sakta hai (yeh hai monitor lock). Ek cook banana chahta hai lekin koi anday nahi hain. Door block karte hue khade rehne ke bajaye, cook bahar nikal ke ek special bench par so jaata hai (wait), taaki doosre cooks kitchen use kar sakein. Jab koi anday laata hai, woh ghanti bajaata hai (signal) ek so rahe cook ko jagaane ke liye (ya broadcast sabke liye). Jaga hua cook wapas andar jaata hai lekin use fridge dobara check karna hi padta hai — kyunki koi aur ne pehle anday utha liye honge. Yahi re-check hai woh while loop!


Active Recall

Ek monitor automatically kya do cheezein bundle karta hai?
Shared data + procedures jo ek automatic mutual-exclusion lock se protected hain (ek time par sirf ek thread andar).
wait ko while mein kyun wrap karna chahiye, na ki if mein?
Mesa semantics ke under predicate signal aur lock re-acquire ke beech phir se false ho sakta hai; while use dobara test karta hai (spurious wakeups & broadcast bhi handle karta hai).
wait(cv) kaunse teen sub-actions perform karta hai, aur woh atomic kyun hone chahiye?
Lock release karo, CV par enqueue karo, so jao — lost-wakeup race se bachne ke liye atomic hona zaroori hai jahan signal thread ke sone se pehle fire kar de.
Hoare aur Mesa signalling mein kya antar hai?
Hoare: signaller turant jaage hue thread ko lock de deta hai (predicate guaranteed true → if theek hai). Mesa: signaller run/lock rakhta hai, jaaga hua thread sirf ready ho jaata hai (predicate stale → while).
Condition variable semaphore counter jaisi kyun NAHI hai?
CV memoryless hai: koi waiters nahi toh signal hamesha ke liye lost ho jaata hai; semaphore ki value V() ko yaad rakhti hai.
signal ki jagah broadcast kab use karna chahiye?
Jab kai waiters alag predicates par ek CV share karke wait karte hain, ya jab ek state change kai waiters ko satisfy kar sakta ho; broadcast har ek ko re-test aur proceed karne deta hai.
Bounded buffer mein do condition variables (notFull, notEmpty) kyun use karte hain?
Woh alag conditions represent karte hain; sahi wali ko signal karne se woh thread nahi jaagti jo proceed nahi kar sakti, wasted wakeups/deadlock se bachta hai.
Kaun se real systems Mesa semantics use karte hain?
pthreads, Java, Python threading.Condition, Go — practically sab.

Connections

  • Semaphores — lower-level primitive; monitors aksar inhi ke upar banaye jaate hain.
  • Mutual Exclusion — woh automatic guarantee jo monitor provide karta hai.
  • Producer-Consumer Problem — monitor ka canonical use case.
  • Deadlock — galat CV choice / missed signal isse cause kar sakta hai.
  • Race Conditions — lost-wakeup woh race hai jo wait ki atomicity prevent karti hai.
  • Spurious Wakeups — doosra reason kyun while mandatory hai.

Concept Map

provides

contains

only one thread inside

is

atomically drops lock

blocks caller on

wakes one from

wakes all from

is

requires

requires

re-tests before

Monitor safe room

Automatic mutex lock

Condition variable

Queue of sleeping threads

wait

signal

broadcast

while predicate loop

Memoryless - lost signal

Spurious wake-ups