Synchronization PrimitivesSemaphoresEasy⏱️ ~2 min

Using Semaphores for Signaling

Key Insight
Signaling means one thread tells another that something has happened. This guarantees that statement a1 in Thread A completes before statement b1 in Thread B begins.
Signaling Pattern (sem = 0)
Thread A1. statement a12. sem.signal()3. continues...Thread B1. sem.wait() - BLOCKS2. statement b13. continues...wakes

Why Initialize To Zero?

Starting at zero means Thread B will block immediately on wait(). It cannot proceed until Thread A calls signal(). This creates a happens-before relationship: a1 happens before b1.

The Guarantee

No matter how the scheduler interleaves these threads, b1 cannot run before a1 completes. If B runs first, it blocks. If A runs first, it signals before B even tries to wait. Either way, the ordering is enforced.

Think Of It Like A Relay Race

Thread A runs its leg of the race, then passes the baton (signals). Thread B waits at the handoff point until the baton arrives, then starts running. The baton ensures B does not start early.

Pattern: Initialize semaphore to 0. The waiting thread calls wait(). The signaling thread calls signal() after completing its work.
💡 Key Takeaways
Signaling ensures one event happens before another across threads. Initialize semaphore to 0 for signaling.
Thread A signals after completing work. Thread B waits before starting dependent work.
Order of arrival does not matter. If B waits first, it blocks. If A signals first, B continues immediately when it arrives.
The semaphore remembers the signal. Unlike condition variables, a signal is not lost if no one is waiting.
This pattern is the foundation for more complex synchronization like barriers and rendezvous.
📌 Examples
1Thread A reads file, signals done. Thread B waits for done, then processes data. File read guaranteed before processing.
2Initialization pattern: main thread signals ready after setup, worker threads wait before starting work.
← Back to Semaphores Overview