Semaphores are often confused and characterized as just a more general form of a mutex. There’s actually some big differences though. I’m also going to explain some differences between the simple lock of the last episode and a mutex.
Because you can declare a semaphore to only allow a single thread at a time to successfully wait on the semaphore, it’s often described as a more general purpose mutex. After all, a mutex can only ever allow a single thread to obtain the lock. But don’t be fooled by this similarity. Use a mutex when you want to guarantee exclusive access to a specific resource. And use a semaphore when you want to signal to some other threads that one or more resources are available.
Another difference between how semaphores are used vs. how mutexes are used is in what operations are called. For a mutex, you have many different threads that each want to obtain the mutex so they each lock it. Only one of the threads will get the lock right away and the other threads will all block. Each thread that uses a mutex will call lock and then release in that order.
Semaphores are not meant to be used like this. They also have two operations but there’s a good reason that the method names are different. With a semaphore, each thread needs to figure out which side it’s on and it should only call that one method. If a thread is making things available to other threads and needs to signal that something is ready, then it should call signal. And if a thread is waiting on something to be ready and then consuming items, then it should call wait.
Just be aware that semaphores by themselves don’t actually protect specific resources. You’ll still want to use one or more mutexes for this purpose.