43.4 Semaphores

The semaphore is a counting lock that permits up to a certain number of threads to acquire it. The number of threads permitted to hold a semaphore at any given time is a parameter to the initialization function.

Imagine a railroad segment with only one set of rails. Rail traffic can proceed up and down the tracks, but in only one direction at a time. In the early days of railroading, there was a track adornment called a semaphore that displayed the current direction of traffic on the track. As long as it indicated that traffic was flowing in the direction a new train was going, that train could venture out onto the tracks without risking a head-on collision.

In software terms, the equivalent of a head-on collision is data corruption or the reading of potentially incomplete or corrupt data. One example might be a licensing check system that permits a database (perhaps with a file descriptor) to be in use by a set number of users. Each potential user (as represented by a thread) would attempt to acquire use of the semaphore by waiting on it. Once a legal thread posted its end of use, the next thread waiting would gain access to the database.

When the semaphore is allocated, the semaphore counter is set to the maximum number of users that can acquire the resource. As each user acquires the resource, the counter is decremented. When the counter reaches 0, no more users can acquire the resource until another user releases the resource. The counter can become negative. If a user calls a semaphore wait function when the counter has a current value of 0, the counter is decremented to a -1.

When a user releases a resource, the counter is incremented. If a user is waiting, the user is notified so that the user can acquire the freed resource. If multiple users are waiting, no assumptions should be made about which user is notified about the resource.

LibC supports semaphores on the NKS, pthreads, and UI interfaces. For a list of the various functions, see Semaphore Interface Comparison.

LibC also supports System-V semaphores. This is the only supported semaphore interface that allows you to create a global semaphore that can be shared with multiple applications. For more information, see System-V Semaphore Functions.