Semaphore Using Mutex and Condition Variables
Mutex is a mutual exclusion device. It is used for the purpose of synchronization while executing concurrent threads. It has two states – unlocked ie. not owned by anyone and locked ie. owned one thread. If a thread try to acquire a locked mutex, the thread gets suspended temporarily.
Actions upon mutex are:
First step will lock the mutex and second step will release the lock.
Semaphore is a more generalized synchronization mechanism. Semaphore is similar to an integer, with only slight differences. While mutex can be in only two states locked or unlocked, semaphore can have integer value 0 or more.
There are two basic operations defined on semaphores:
- up or post – this will increment the value of the semaphore by one.
- down or wait – this will decrement the value of the semaphore by one, but if the value is already 0 the thread will be suspended until another post occurs.
Condition Variables are helpful in solving some synchronization problems easily compared to situations which are made complex using semaphores or mutex. Condition variables are usually used in association with mutex.
There are two basic operations performed on condition variables:
- wait – it will make the running thread sleep and releases lock acquired by it.
- broadcast – it will wake up the threads that went to sleep when it encountered wait. The threads reacquire the lock and continue the execution.
We can implement the semaphore using both mutex and condition variables. Get the complete code here.
The following structure is the main part:
The integer value val is used as the integer associated with semaphore. Variable mutex is the mutex variable and cond is the condition variable.
We require three functions:
The first function init initializes the semaphore. down decrements the value of the integer val by 1 if the val is not 0. If the value is 0 the function calls the operation wait of condition variable, which blocks the thread and release the lock. up increments the value of val by 1 and also use broadcast operation of condition variable to wake up the threads which went asleep in down, if any.
The important thing to remember is, with one up only a corresponding down can be performed. This is taken care by the while loop.