The concept of semaphores is used for synchronization.
Semaphore is an integer with a difference. Well, actually a few differences.
You set the value of the integer when you create it, but can never access the value directly after that; you must use one of the semaphore functions to adjust it, and you cannot ask for the current value.
There are semaphore functions to increment or decrement the value of the integer by one.
Decrementing is a (possibly) blocking function. If the resulting semaphore value is negative, the calling thread or process is blocked, and cannot continue until some other thread or process increments it.
Incrementing the semaphore when it is negative causes one (and only one) of the threads blocked by this semaphore to become unblocked and runnable.
Therefore, all semaphore operations are atomic. Implemented in kernel,