Initializing Semaphores With Interprocess Scope
When pshared is nonzero, the semaphore can be shared by other processes.
#include <semaphore.h> sem_t sem; int ret; int count = 4; /* to be shared among processes */ ret = sem_init(&sem, 1, count); |
Named Semaphores
The functions sem_open(3RT), sem_getvalue(3RT), sem_close(3RT), and sem_unlink(3RT) are available to open, retrieve, close, and remove named semaphores. Using sem_open(), you can create a semaphore that has a name defined in the file system name space.
Named semaphores are like process shared semaphores, except that they are referenced with a pathname rather than a pshared value.
For more information about named semaphores, see sem_open(3RT), sem_getvalue(3RT), sem_close(3RT), and sem_unlink(3RT).
Increment a Semaphore
sem_post(3RT)
Prototype: int sem_post(sem_t *sem); |
#include <semaphore.h> sem_t sem; int ret; ret = sem_post(&sem); /* semaphore is posted */ |
Use sema_post(3THR) to atomically increment the semaphore pointed to by sem. When any threads are blocked on the semaphore, one of them is unblocked. (For Solaris threads, see "sema_post(3THR)".)
Return Values
sem_post() returns zero after completing successfully. Any other return value indicates that an error occurred. When the following condition occurs, the function fails and returns the corresponding value.
sem points to an illegal address.
Block on a Semaphore Count
sem_wait(3RT)
Prototype: int sem_wait(sem_t *sem); |
#include <semaphore.h> sem_t sem; int ret; ret = sem_wait(&sem); /* wait for semaphore */ |
Use sema_wait(3THR) to block the calling thread until the count in the semaphore pointed to by sem becomes greater than zero, then atomically decrement it.
Return Values
sem_wait() returns zero after completing successfully. Any other return value indicates that an error occurred. When any of the following conditions occurs, the function fails and returns the corresponding value.
sem points to an illegal address.
A signal interrupted this function.
Decrement a Semaphore Count
sem_trywait(3RT)
Prototype: int sem_trywait(sem_t *sem); |
#include <semaphore.h> sem_t sem; int ret; ret = sem_trywait(&sem); /* try to wait for semaphore*/ |
Use sem_trywait(3RT) to try to atomically decrement the count in the semaphore pointed to by sem when the count is greater than zero. This function is a nonblocking version of sem_wait(); that is it returns immediately if unsuccessful.
Return Values
sem_trywait() returns zero after completing successfully. Any other return value indicates that an error occurred. When any of the following conditions occurs, the function fails and returns the corresponding value.
sem points to an illegal address.
A signal interrupted this function.
The semaphore was already locked, so it cannot be immediately locked by the sem_trywait() operation.
Destroy the Semaphore State
sem_destroy(3RT)
Prototype: int sem_destroy(sem_t *sem); |
#include <semaphore.h> sem_t sem; int ret; ret = sem_destroy(&sem); /* the semaphore is destroyed */ |
Use sem_destroy(3RT) to destroy any state associated with the semaphore pointed to by sem. The space for storing the semaphore is not freed. (For Solaris threads, see "sem_destroy(3THR)".)
Return Values
sem_destroy() returns zero after completing successfully. Any other return value indicates that an error occurred. When the following condition occurs, the function fails and returns the corresponding value.
sem points to an illegal address.
The Producer/Consumer Problem, Using Semaphores
The data structure in Example 4-14 is similar to that used for the condition variables example (see Example 4-11). Two semaphores represent the number of full and empty buffers and ensure that producers wait until there are empty buffers and that consumers wait until there are full buffers.
Example 4-14 The Producer/Consumer Problem With Semaphores
Another pair of (binary) semaphores plays the same role as mutexes, controlling access to the buffer when there are multiple producers and multiple empty buffer slots, and when there are multiple consumers and multiple full buffer slots. Mutexes would work better here, but would not provide as good an example of semaphore use.
Example 4-15 The Producer/Consumer Problem--the Producer
void producer(buffer_t *b, char item) { sem_wait(&b->empty); sem_wait(&b->pmut); b->buf[b->nextin] = item; b->nextin++; b->nextin %= BSIZE; sem_post(&b->pmut); sem_post(&b->occupied); } |
Example 4-16 The Producer/Consumer Problem--the Consumer