POSIX semaphores differ from the set of System V semaphores, and the POSIX semaphore is a single semaphore, divided into known semaphores and nameless semaphores.
POSIX-known semaphores are semaphores with POSIX IPC names that can be used for synchronization between processes and threads; a POSIX nameless semaphore is a memory-based semaphore stored in a shared memory area for synchronization between processes and threads.
POSIX-known semaphores can be kernel maintenance, or can be maintained in the file system, depending on whether the semaphore corresponds to the path name mapped to a real disk file, if there is a mapping to the file system maintenance, otherwise maintained in the kernel, POSIX known semaphore by the function Sem_open (), SEM _close (), Sem_unlink (), sem_wait (), sem_trywait (), Sem_post (), Sem_getvalue () to operate using.
The POSIX nameless semaphore is divided between process sharing and thread sharing according to the input parameters of the Sem_init () function call, function prototype int sem_init (sem_t *sem,int shared,unsigned int value); The second parameter, shared with 0, is shared between threads, and if shared is 1, it is an inter-process share, while the first parameter variable sem_t data type variable SEM must reside in the memory area shared by all the processes that want to share it. POSIX nameless semaphores are manipulated using the function Sem_init (), Sem_destroy (), sem_wait (), sem_trywait (), Sem_post (), Sem_getvalue ().
POSIX semaphore correlation function prototypes and header files:
#include <semaphore.h>
sem_t *sem_open (const char*name,int oflag,.../*mode_t mode, unsigned int value*/);
Function: Create a new known semaphore or open a known semaphore that already exists
Return value: If a pointer to the semaphore is successfully returned, the pointer is used as a parameter to Sem_close (), sem_wait (), sem_trywait (), Sem_post,sem_getvalue (), and if an error is returned sem_failed.
Parameter: name is the pathname; Oflag can be 0,o_creat or o_creat| The O_excl;mode parameter optional is the specified permission bit, which is valid in O_creat, the value parameter is the initial value of the specified semaphore, cannot exceed Sem_value_max, the initial value of the binary semaphore is usually 1, and the count semaphore initial value is usually greater than 1.
int Sem_close (sem_t *sem);
Function: Turns off the well-known semaphore opened by Sem_open ().
Return value: If successful return 0, if failure returns-1
int Sem_unlink (const char *name);
Function: Really remove the semaphore from the system
Return value: If successful return 0, if failure returns-1
int sem_wait (sem_t *sem);
Function: Tests the value of the specified semaphore, minus 1 if the value is greater than 0, and returns immediately if the value equals 0, the calling process or thread blocks into sleep until the value becomes greater than 0, and then the function returns. This "test sickness minus 1" operation must be atomic.
Return value: Successfully returned 0, error returned-1
int sem_trywait (sem_t *sem);
Function: Same as sem_wait (), only when the specified semaphore being tested is 0 o'clock, does not block into sleep, but returns a Eagain error.
Return value: Successfully returned 0, error returned-1
int Sem_post (sem_t *sem);
Function: Adds 1 to the specified semaphore, and then wakes up any process or thread that is waiting for the semaphore value to become a positive number.
Return value: Successfully returned 0, error returned-1
int Sem_getvalue (sem_t *sem, int *valp);
Function: Gets the current value of the specified semaphore into the Valp pointer, and if the semaphore is locked, gets a value of 0 or a negative number, the absolute amount of the thread waiting for the semaphore to be unlocked.
Return value: Successfully returned 0, error returned-1.
int Sem_int (sem_t *sem, int shared, unsigned int value);
Function: Initializes an unnamed semaphore for POSIX shared memory.
Return value: Error returned-1.
Parameters: SEM is a pointer to the semaphore; shared is 0 thread sharing, and 1 is process sharing (SEM needs to reside shared memory); value is the initialization value.
int sem_destory (sem_t *sem);
Function: Destroys the nameless semaphore initialized by Sem_init ().
Return value: Successfully returned 0, error returned-1
code example, the parent-child process uses a binary semaphore sem_test.c:
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <semaphore.h>
- #include <fcntl.h>
- #define USE_POSIX_SEM 1
- #define MYSEM "/mysem"
- #define Run_times 5
- int main (void)
- {
- #if Use_posix_sem
- Sem_t *semid;
- int Val;
- Sem_unlink (Mysem);
- Semid=sem_open (mysem,o_creat,0666,0);
- if (Sem_failed==semid)
- {
- printf ("Sem open failed!\n");
- return 0;
- }
- Sem_getvalue (Semid,&val);
- printf ("Sem_val init=%d\n", Val);
- Sem_post (Semid);
- Sem_getvalue (Semid,&val);
- printf ("Sem_val after Post=%d\n", Val);
- #endif
- int pid=fork ();
- if (0==pid)
- {
- int i;
- #if Use_posix_sem
- Sem_wait (Semid);
- #endif
- for (i=0;i<run_times;i++)
- {
- printf ("Child running!\n");
- Sleep (1);
- }
- #if Use_posix_sem
- Sem_post (Semid);
- #endif
- printf ("Child end\n");
- Exit (0);
- }
- else if (pid>0)
- {
- int i;
- #if Use_posix_sem
- Sem_wait (Semid);
- #endif
- for (i=0;i<run_times;i++)
- {
- printf ("Parent running!\n");
- Sleep (1);
- }
- #if Use_posix_sem
- Sem_post (Semid);
- #endif
- printf ("Parent end\n");
- }
- Waitpid (pid,null,0);
- printf ("Progam finished\n");
- #if Use_posix_sem
- Sem_close (Semid);
- Sem_unlink (Mysem);
- #endif
- return 0;
- }
Copy Code
Operation Result:
$./a.out
Sem_val init=0
Sem_val after Post=1
Parent running!
Parent running!
Parent running!
Parent running!
Parent running!
Parent End
Child running!
Child running!
Child running!
Child running!
Child running!
Child End
Progam finished
As you can see, the parent process executes before the child process executes 5 times after the post semaphore has been printed.
If you turn off the POSIX semaphore, the conditional compilation macro is set to "#define USE_POSIX_SEM 0" and the result is:
$./a.out
Parent running!
Child running!
Parent running!
Child running!
Parent running!
Child running!
Parent running!
Child running!
Child running!
Parent running!
Parent End
Child End
Progam finished
You can see that the parent-child process is alternately executed and there is a competitive relationship.
Examples of POSIX semaphore usage details for Linux interprocess communication