Journal Entry Week 6- CST334
This week in CST 334, I focused on semaphores and why they can be both powerful and frustrating. A semaphore is essentially a counter with two main operations: wait, which decrements the counter, and signal, which increments it. If a wait call makes the counter drop below zero, the thread pauses until another thread signals. On the surface, the idea is simple, but using them well requires keeping track of what the counter represents at every point in your program. That constant mental tracking is what makes them challenging. Unlike condition variables, semaphores can hold a signal so a thread arriving later can still move forward. This feature can be useful if planned for, or cause bugs if it is not.
We explored several patterns that show how semaphores can coordinate work. The signal pattern ensures one piece of code finishes before another begins. The rendezvous pattern makes two threads meet at a specific point before either can continue. The barrier pattern expands this to multiple threads, holding all of them until everyone arrives. The reusable barrier was the most interesting example. It uses a counter to track arrivals and a turnstile effect so each thread lets the next one through, avoiding busy waiting. Seeing the drop in CPU usage when busy waiting was replaced with semaphore-based waiting made the benefits clear. My main takeaway is that semaphores can replace both locks and condition variables, but they demand careful design and a precise understanding of thread execution order to avoid deadlocks and subtle timing issues.
Comments
Post a Comment