Avoid undesired race conditions. Identify pieces of code that should run atomically. Using atomic operations to ensure correct operation of cooperating processes. So, we introduce more powerful atomic operators. No negative values, 2.
Operations are atomic.
Often used to implement critical sections. For example, if there are 3 buffers, set initial value of semaphore to 3. If nobody is in a critical section and a process wants in, it should be allowed in. No process should be blocked forever. No process will stay in critical section forever 3.