Semaphores are a good way to learn about synchronization, but they are not as widely used, in practice, as mutexes and condition variables.
Nevertheless, there are some synchronization problems that can be solved simply with semaphores, yielding solutions that are more demonstrably correct.
This chapter presents a C API for working with semaphores and my code for making it easier to work with. And it presents a final challenge: can you write an implementation of a semaphore using mutexes and condition variables?
The code for this chapter is in directory semaphore in the repository for this book (see Section 0.2).