For mutual exclusion one of the simplest is the pair sleep and wakeup. Sleep is a system call that causes the caller to block, that is, be suspended until another process wakes it up. The wakeup call has one parameter, the process to be awakened.

Alternatively, both sleep and wakeup each have one parameter, a memory address used to match up sleeps with wakeups.

Semaphores

Semaphore is a simply a variable. This variable is used to solve critical section problem and to achieve process synchronization in the multiprocessing environment.

The two most common kinds of semaphores are counting semaphores and binary semaphores. Counting semaphore can take non-negative integer values and Binary semaphore can take the value 0 & 1 only.

A semaphore can only be accessed using the following operations:

  • wait () :- called when a process wants access to a resource
  • signal ():- called when a process is done using a resource

int s = 1;

wait (Semaphore s)

{

while (s==0);           /* wait until s>0 */ s=s-1;

}

signal (Semaphore s)

{

s=s+1;

}

Here is an implementation of mutual-exclusion using binary semaphores:

do

{

wait(s);

// critical section

signal(s);

// remainder section

} while(1);

Now, let us see how it implements mutual exclusion. Let there be two processes P1 and P2 and a semaphore s is initialized as 1. Now if suppose P1 enters in its critical section then the value of semaphore s becomes 0. Now if P2 wants to enter its critical section then it will wait until s>0, this can only happen when P1 finishes its critical section and calls signal() operation on semaphore s. This way mutual exclusion is achieved. Look at the below image for details.

Historically, wait() was called signal() was called V i.e.