14.3 POSIX:SEM Unnamed Semaphores

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.11

The 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 .

errno

cause

EINVAL

value is greater than SEM_VALUE_MAX

ENOSPC

initialization resource was exhausted, or number of semaphores exceeds SEM_NSEMS_MAX

EPERM

caller does not have the appropriate privileges

Example 14.12

The 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.13

The following code destroys semA .

 sem_t semA; if (sem_destroy(&semA) == -1)    perror("Failed to destroy semA"); 
Exercise 14.14

What 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


Unix Systems Programming
UNIX Systems Programming: Communication, Concurrency and Threads
ISBN: 0130424110
EAN: 2147483647
Year: 2003
Pages: 274

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net