The potential learning curve of System V semaphores is much higher when compared to POSIX semaphores. This will be more understandable after you go through this section and compare it to what you learned in the previous section.
To start with, POSIX comes with simple semantics for creating, initializing, and performing operations on semaphores. They provide an efficient way to handle interprocess communication. POSIX comes with two kinds of semaphores: named and unnamed semaphores.
Named Semaphores
If you look in the man pages, you'll see that a named semaphore is identified by a name, like a System V semaphore, and, similarly, the semaphores have kernel persistence. This implies that these semaphores, like System V, are system-wide and limited to the number that can be active at any one time. The advantage of named semaphores is that they provide synchronization between unrelated process and related process as well as between threads.
A named semaphore is created by calling following function:
sem_t *sem_open(const char *name, int oflag, mode_t mode , int value);
- name
- Name of the semaphore to be identified.
- oflag
- Is set to
O_CREAT
for creating a semaphore (or withO_EXCL
if you want the call to fail if it already exists). - mode_t
- Controls the permission setting for new semaphores.
- value
- Specifies the initial value of the semaphore.
A single call creates the semaphore, initializes it, and sets permissions on it, which is quite different from the way System V semaphores act. It is much cleaner and more atomic in nature. Another difference is that the System V semaphore identifies itself by means of type int (similar to a fd returned from
open()
), whereas the sem_open
function returns type sem_t
, which acts as an identifier for the POSIX semaphores.From here on, operations will only be performed on semaphores. The semantics for locking semaphores is:
int sem_wait(sem_t *sem);
This call locks the semaphore if the semaphore count is greater than zero. After locking the semaphore, the count is reduced by 1. If the semaphore count is zero, the call blocks.
The semantics for unlocking a semaphore is:
int sem_post(sem_t *sem);
This call increases the semaphore count by 1 and then returns.
Once you're done using a semaphore, it is important to destroy it. To do this, make sure that all the references to the named semaphore are closed by calling the
sem_close()
function, then just before the exit or within the exit handler call sem_unlink()
to remove the semaphore from the system. Note that sem_unlink()
would not have any effect if any of the processes or threads reference the semaphore.Unnamed Semaphores
Again, according to the man pages, an unnamed semaphore is placed in a region of memory that is shared between multiple threads (a thread-shared semaphore) or processes (a process-shared semaphore). A thread-shared semaphore is placed in a region where only threads of an process share them, for example a global variable. A process-shared semaphore is placed in a region where different processes can share them, for example something like a shared memory region. An unnamed semaphore provides synchronization between threads and between related processes and are process-based semaphores.
The unnamed semaphore does not need to use the
sem_open
call. Instead this one call is replaced by the following two instructions:{ sem_t semid; int sem_init(sem_t *sem, int pshared, unsigned value); }
- pshared
- This argument indicates whether this semaphore is to be shared between the threads of a process or between processes. If pshared has value 0, then the semaphore is shared between the threads of a process. If pshared is non-zero, then the semaphore is shared between processes.
- value
- The value with which the semaphore is to be initialized.
Once the semaphore is initialized, the programmer is ready to operate on the semaphore, which is of type
sem_t
. The operations to lock and unlock the semaphore remains as shown previously: sem_wait(sem_t *sem)
and sem_post(sem_t *sem)
. To delete a unnamed semaphore, just call the sem_destroy
function.The last section of this article has a simple worker-consumer demo that has been developed by using a POSIX semaphore.
No comments:
Post a Comment