Synchronization Primitives • SemaphoresEasy⏱️ ~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)
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.