This material is taken from the first 16 pages of Chapter 14 of USP
The POSIX standard defines several different kinds of semaphores.
This short note describes only one of these, the POSIX:SEM unnamed semaphores.
These semaphores are ideal for working with POSIX threads.
To use these semaphores, include semaphore.h.
You might also
have to link to a particular library when compiling your program,
With Linux, you can use just -lpthread if you are using POSIX
threads.
If you are just using the semaphores, you can use -lrt.
A semaphore has type sem_t and is declared in the usual way:
sem_t sem;
declares a semaphore called sem.
A semaphore needs to be initialized before it is used:
int sem_init(sem_t *sem, int pshared, unsigned value)
If pshared is not zero, the semaphore can be used by any process that
can access the semaphore, but this is not very useful since it is difficult
for multiple processes to share one of these semaphores.
If you create a semaphore and fork a child, the child gets a copy of the
semaphore and so it cannot be used for synchronization between parent and child.
All of the functions related to these semaphores return 0 on success and -1 on failure with errno set to indicate the type of error.
The main semaphore operations are called sem_post (instead
of signal) and sem_wait.
There is also a sem_trywait.
Each of these takes a single parameter that is a pointer to a semaphore.
The sem_wait function can return -1 with errno set to EINTR, so you should call this in a loop as illustrated below.
Program 14.2 on page 497 shows an example of protecting a shared variable using a semaphore.
Program 14.5 shows a thread that is passed a semaphore used for protection
of a critical section.
The critical section just prints a message, one character at a time with a
slight delay between characters.
Program 14.6 is a corresponding main program.
The program solution_buffer shows how to create a simple buffer that can be shared among threads.