Team-FLY |
A POSIX:SEM semaphore is a variable of type sem_t with associated atomic operations for initializing, incrementing and decrementing its value. The POSIX:SEM Semaphore Extension defines two types of semaphores, named and unnamed. An implementation supports POSIX:SEM semaphores if it defines _POSIX_SEMAPHORES in unistd.h . The difference between unnamed and named semaphores is analogous to the difference between ordinary pipes and named pipes (FIFOs). This section discusses unnamed semaphores. Named semaphores are discussed in Section 14.5. Example 14.11The following code segment declares a semaphore variable called sem . #include <semaphore.h> sem_t sem; The POSIX:SEM Extension does not specify the underlying type of sem_t . One possibility is that sem_t acts like a file descriptor and is an offset into a local table. The table values point to entries in a system table. A particular implementation may not use the file descriptor table model but instead may store information about the semaphore with the sem_t variable. The semaphore functions take a pointer to the semaphore variable as a parameter, so system implementers are free to use either model. You may not make a copy of a sem_t variable and use it in semaphore operations. POSIX:SEM semaphores must be initialized before they are used. The sem_init function initializes the unnamed semaphore referenced by sem to value . The value parameter cannot be negative. Our examples use unnamed semaphores with pshared equal to 0, meaning that the semaphore can be used only by threads of the process that initializes the semaphore. If pshared is nonzero, any process that can access sem can use the semaphore. Be aware that simply forking a child after creating the semaphore does not provide access for the child. The child receives a copy of the semaphore, not the actual semaphore. SYNOPSIS #include <semaphore.h> int sem_init(sem_t *sem, int pshared, unsigned value); POSIX:SEM If successful, sem_init initializes sem . Interestingly, POSIX does not specify the return value on success, but the rationale mentions that sem_init may be required to return 0 in a future specification. If unsuccessful , sem_init returns “1 and sets errno . The following table lists the mandatory errors for sem_init .
Example 14.12The following code segment initializes an unnamed semaphore to be used by threads of the process. sem_t semA; if (sem_init(&semA, 0, 1) == -1) perror("Failed to initialize semaphore semA"); The sem_destroy function destroys a previously initialized unnamed semaphore referenced by the sem parameter. SYNOPSIS #include <semaphore.h> int sem_destroy(sem_t *sem); POSIX:SEM If successful, sem_destroy returns 0. If unsuccessful, sem_destroy returns “1 and sets errno . The sem_destroy function sets errno to EINVAL if *sem is not a valid semaphore. Example 14.13The following code destroys semA . sem_t semA; if (sem_destroy(&semA) == -1) perror("Failed to destroy semA"); Exercise 14.14What happens if Example 14.13; executes after semA has already been destroyed ? What happens if another thread or process is blocked on semA when the sem_destroy function is called? Answer: The POSIX standard states that the result of destroying a semaphore that has already been destroyed is undefined. The result of destroying a semaphore on which other threads are blocked is also undefined. |
Team-FLY |