5 Condition variables and semaphores

 

This chapter covers

  • Waiting on conditions with condition variables
  • Implementing a write preferring readers-writer lock
  • Storing signals with counting semaphores

In the previous chapter we saw how we can use mutexes to protect critical sections of our code and synchronize multiple goroutines from executing at the same time. Mutexes are not the only synchronization tool that we have available. Condition variables give us extra controls that complement exclusive locking. They give us the control to wait on a certain condition to occur before unblocking the execution. Semaphores go one step further than mutexes in that they allow us to control how many concurrent goroutines we allow to execute a certain section at the same time. In addition, semaphores can be used as a way to store a signal to an execution.

Apart from being useful in our concurrent applications, condition variables and semaphores are additional primitive building blocks that we can use to build more complex tools and abstractions. In this chapter we will also re-examine our read write lock, developed in the previous chapter, and improve it using condition variables.

5.1 Condition variables

Condition variables give us extra functionality on top of mutexes. We use them in situations where a goroutine needs to block and wait for a particular condition to occur. Let’s have a look at an example to understand how they’re used.

5.1.1 Combining mutexes with condition variables

5.1.2 Missing the signal

5.1.3 Synchronizing multiple goroutines with waits and broadcasts

5.1.4 Revisiting readers-writer locks using condition variables

5.2 Counting semaphores

5.2.1 What’s a semaphore?

5.2.2 Building a semaphore

5.2.3 Never miss a signal with semaphores

5.3 Summary

5.4 Exercises