Linux Environment Programming Synchronization (IV): POSIX semaphore

Source: Internet
Author: User
Tags posix semaphore

Semaphores are primitives used to provide synchronization between different threads of different processes or a given process. There are three types: POSIX-known semaphores , using POSIX IPC name identifiers,POSIX memory-based semaphores , stored in shared memory areas, andSystem v semaphores , maintained in the kernel. These three semaphores can be used for synchronization between processes or threads.


Figure 1 A two-value semaphore used by two processes


Figure 2 A POSIX-known binary semaphore used by two processes


Figure 3 Memory-based semaphores shared by two threads in a process

Three operations that a process can perform on a semaphore:

1, Create a semaphore , which requires the caller to specify the initial value, for the binary semaphore, it is usually 1, but also 0.

2, waiting for a semaphore , the operation will test the value of this semaphore, if less than 0, blocking. Also known as the P operation.

3. hang out a semaphore , which adds 1 to the value of the semaphore, also known as the V operation.

Three differences between semaphores, mutexes, and condition variables:

1. The mutex must always give it a locked line threads unlocked, and the semaphore's hang-out does not have to be performed by the same thread that performed the wait operation.

2, the mutual exclusion lock is either locked or untied.

3, since the semaphore has a state associated with it, then the semaphore hanging operation is always remembered. When a signal is sent to a condition variable, however, if no thread waits on the condition variable, the signal is lost.


POSIX provides two types of semaphores: well-known semaphores and memory-based semaphores (also known as nameless semaphores ). Use the function as follows:


#include <semaphore.h>/*sem_open Create a new known semaphore or open an existing known semaphore, the value parameter specifies the initial value of the semaphore, and the return value is a pointer to a sem_t data type. Parameter */sem_t*sem_open (const char *name, int oflag, .../*mode_t mode, unsigned int value*/) as other functions; Intsem_close (sem_t *sem); /* When a process terminates, the kernel automatically performs a shutdown operation on all semaphores that are still open */int sem_unlink (const char *name); /*sem_unlink function: When the reference count is greater than 0 o'clock, name can be removed from the file system, but the destruction of the semaphore will wait until the last sem_close occurs */int sem_wait (sem_t *sem); /* Test the value of the specified semaphore, greater than 0, minus 1 and return, equal to 0, calling the thread to hibernate until the value is greater than 0, minus 1, and the function then returns */int sem_trywait (sem_t *sem); /* The semaphore value specified is 0 o'clock, does not hibernate, but returns a eagain error */int sem_post (sem_t *sem); int Sem_getvalue (sem_t *sem, int  *valp);/* Returns the current value of the specified semaphore from the integer pointed to by Valp. */
Semcreate Program:

#include <semaphore.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include < fcntl.h> #include <sys/stat.h> #include <sys/types.h> #define File_mode (s_irusr | S_IWUSR | S_irgrp | S_iroth) intmain (int argc, char **argv) {int c, flags;sem_t*sem;unsigned int value;flags = O_RDWR | O_creat;value = 1;while ((c = getopt (argc, argv, "EI:"))! =-1) {switch (c) {case ' E ': Flags |= o_excl;case ' i ': value = Atoi (op Targ); break;}} if (optind! = argc-1) {printf ("usage:semcreate [-e] [-I initalvalue] <name>\n"); return-1;} SEM = Sem_open (Argv[optind], flags, file_mode, value); Sem_close (SEM); exit (0);
Semunlink Program:

#include <semaphore.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h>intmain (int ARGC, char **argv) {if (argc! = 2) {printf ("Usage:semunlink <name>.\n"); return-1;} Sem_unlink (argv[1]); exit (0);}
Semgetvalue Program:

#include <semaphore.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h>intmain (int ARGC, char **argv) {sem_t *sem;int val;if (argc! = 2) {printf ("Usage:semgetvalue <name>.\n"); return-1;} SEM = Sem_open (argv[1], 0), Sem_getvalue (SEM, &val);p rintf ("value =%d\n", val); exit (0);}
Semwait Program:

#include <semaphore.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h>intmain (int ARGC, char **argv) {sem_t*sem;int val;if (argc! = 2) {printf ("usage:semwait <name>"); return-1;} SEM = Sem_open (argv[1], 0), sem_wait (SEM), Sem_getvalue (SEM, &val);p rintf ("pid%ld has semaphore, value =%d\n", (long) Getpid (), Val);p ause ();/*block until Killed*/exit (0);}
Sempost Program:

#include <semaphore.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h>intmain (int ARGC, char **argv) {sem_t*sem;intval;if (argc! = 2) {printf ("Usage:sempost <name>\n"); return-1;} SEM = Sem_open (argv[1], 0), Sem_post (SEM), Sem_getvalue (SEM, &val);p rintf ("value =%d\n", val); exit (0);}
POSIX memory-based semaphores, where the application allocates a semaphore's memory space (that is, allocates a memory space of the sem_t data type), and then the system initializes their values.

#include <stmaphore.h>intsem_init (sem_t *sem, int shared, unsigned int value);  /* Error returned -1*/int Sem_destroy (sem_t *sem); <span style= "White-space:pre" ></span>/* successfully returned 0, error returned -1*/
The memory-based semaphore is initialized by Sem_init, and the SEM parameter points to the sem_t variable that the application must allocate. If shared is 0, the amount of semaphore to initialize is shared among the threads of the same process, otherwise the semaphore is shared between processes.

When you do not need to use the name associated with a known semaphore, you can use memory-based semaphores instead. A well-known semaphore is typically used when the semaphore is used by different processes that are not related to each other. Its name is the means by which each process identifies the semaphore. Memory-based semaphores have at least process continuity, but their true durability depends on the type of memory area in which the semaphore is stored. This semaphore persists as long as the memory area containing a memory semaphore remains valid.

Shared semaphores between processes

The rules for sharing memory-based semaphores between processes are simple: the semaphore itself must reside in a memory area shared by all the processes that want to share it, and the second parameter of Sem_init must be 1.

known semaphores , different processes always have access to the same known semaphore, as long as they specify the same name when calling Sem_open.


Semaphore limit

POSIX defines two semaphore limits:

Sem_nsems_max Maximum number of signals that a process can open simultaneously

Sem_value_max The maximum value of a semaphore

These two constant values are defined in the <unistd.h> header file and can be obtained at run time through the sysconf function.






Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.