The Semaphore Primitive

In ThreadMentor, a semaphore is defined in class Semaphore with two methods: Wait() and Signal(). The constructor of class Semaphore takes two arguments. The first one is a char array that supplies a name of the semaphore, and the second is the initial value of the semaphore counter. Note that the initial value must be a non-negative integer. The initial value is required, and the semaphore name string is optional. If no name string is provided, the semaphore will automatically receive a default name No name.

The use of semaphores is very easy. First, we need to declare a semaphore variable of type Semaphore. Second, use the method Wait() when a thread must wait on the semaphore. Third, use the method Signal() to release a waiting threads. In the following, we have a semaphore Block, with initial value 1, and use Block.Wait() and Block.Signal() to make sure mutual exclusion for a critical section.

Semaphore  Block("MyLock", 1);

Block.Wait();

// critical section

Block.Signal();

If it is necessary, one can use pointer to semaphore. The following is an example:

Semaphore *Block;

Block = new Semaphore("MyLock", 1);

Block->Wait();

// critical section

Block->Signal();

Both examples have a semaphore with name MyLock and initial value 1, and both serve the same purpose of guaranteeing mutual exclusion. It is a good practice to assign names to semaphores because you will easily see which semaphore blocks which threads with our visualization system.

Note that because semaphores are usually used by several threads, they are global data items.

A Historical Note

Semaphores were first proposed by Edsger W. Dijkstra in 1968. Dijkstra, a Dutchman, used P for Wait() because P is the first letter of the Dutch word "passeren," which means "to pass," and V for Signal() because V is the first letter of the Dutch word "vrijgeven," which means "to release." Some books may also use down and up for Wait() and Signal(), respectively.