System V Semaphores
Semaphores enable processes to query or alter status information. They are used to monitor and control the availability of system resources such as shared memory segments. Semaphores can be operated on as individual units or as elements in a set.
Because System V IPC semaphores can be in a large array, they are extremely heavy weight. Much lighter-weight semaphores are available in the threads library. Also, POSIX semaphores are the most current implementation of System V semaphores (see POSIX Semaphores). Threads library semaphores must be used with mapped memory. For more information, see Memory Management Interfaces.
A semaphore set consists of a control structure and an array
of individual semaphores. A set of semaphores can contain up to 25
elements. The semaphore set must be initialized using
semget
(). The semaphore creator can change its
ownership or permissions using semctl
(). Any process
with permission can use semctl
()
to do control
operations. For more information, see the
semget
(2) and
semctl
(2) man pages.
Semaphore operations are performed by
semop
(). This interface takes a pointer to an array
of semaphore operation structures. Each structure in the array contains
data about an operation to perform on a semaphore. Any process with read
permission can test whether a semaphore has a zero value. Operations to
increment or decrement a semaphore require write permission. For more
information, see the
semop
(2) man page.
When an operation fails, none of the semaphores are altered. The
process blocks unless the IPC_NOWAIT
flag is set,
and remains blocked until:
-
The semaphore operations can all finish, so the call succeeds.
-
The process receives a signal.
-
The semaphore set is removed.
Only one process at a time can update a semaphore.
Simultaneous requests by different processes are performed in an
arbitrary order. When an array of operations is given by a
semop
()
call, no updates are done until all operations
on the array can finish successfully.
If a process with exclusive use of a semaphore terminates
abnormally and fails to undo the operation or free the semaphore, the
semaphore stays locked in memory in the state the process left it. To
prevent this occurrence, the SEM_UNDO
control
flag makes semop
()
allocate an undo structure for each
semaphore operation, which contains the operation that returns the
semaphore to its previous state. If the process dies, the system applies
the operations in the undo structures. This prevents an aborted process
from leaving a semaphore set in an inconsistent state. For more
information, see the
semop
(2) man page.
If processes share access to a resource controlled by a semaphore, operations
on the semaphore should not be made with SEM_UNDO
in effect.
If the process that currently has control of the resource terminates abnormally,
the resource is presumed to be inconsistent. Another process must be able
to recognize this to restore the resource to a consistent state.
When performing a semaphore operation with
SEM_UNDO
in effect, you must also have
SEM_UNDO
in effect for the call that performs the
reversing operation. When the process runs normally, the reversing
operation updates the undo structure with a complementary value. This
ensures that, unless the process is aborted, the values applied to the
undo structure are canceled to zero. When the undo structure reaches
zero, it is removed.
Using SEM_UNDO
inconsistently can lead to memory
leaks because allocated undo structures might not be freed until the system
is rebooted.