A common situation in operating systems is to have a bounded buffer shared by 2 processes. The buffer has a finite size, so the producer has to wait when it's full, and the consumer has to wait when it's empty. And, of course, all elements added to the queue by the producer must be seen by the consumer exactly once. This is the common problem that we will use to demonstrate our mutual exclusion systems. This problem demonstrates 2 kinds of semaphore.
Semaphores are simple and powerful, and easy to misconfigure.
Monitors Monitors are a language construct, if they exist, they're part of the language. Monitors need a blocking mechanism, which is provided by condition variables. A condition variable isn't really a variable. It doesn't have a value and processes can't examine it. Condition variables are only synchronization points.