In the POSIX standard, the semaphore is divided into two types, one is the nameless semaphore, and the other is a well-known semaphore. The nameless semaphore is typically used for inter-thread synchronization or mutual exclusion, and a well- known semaphore is typically used for inter-process synchronization or mutual exclusion . Their differences are similar to pipes and named Pipes, where the nameless semaphore is stored directly in memory, and a well-known semaphore requires a file to be created. Before we learned the use of nameless semaphores (see "Nameless semaphores" for details), here we study the use of well-known semaphores.
1) Create a well-known semaphore
Required header file:
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
Used when a known semaphore is present:
sem_t *sem_open (const char *name, int oflag);
Use when a known semaphore does not exist:
sem_t *sem_open (const char *name, int oflag, mode_t mode, unsigned int value);
Function:
Create a well-known semaphore.
Parameters:
name: Semaphore file name. Note that you cannot specify a path name. Because of the known semaphore, the default is placed in the /dev/shm , such as:
flags: The behavior Flags of the Sem_open () function.
mode: The settings for file permissions (readable, writable, executable).
value: The initial value of the semaphore.
return value:
Success: The address of the semaphore
Failure: sem_failed
2) Close the known semaphore
Required header file:
#include <semaphore.h>
int Sem_close (sem_t *sem);
Function:
Turn off the known semaphore.
Parameters:
sem: A pointer to the semaphore.
return value:
Success: 0
Failed:-1
3) Delete the known semaphore file
Required header file:
#include <semaphore.h>
int Sem_unlink (const char *name);
Function:
Deletes a file with a known semaphore.
Parameters:
name: A semaphore file name.
return value:
Success: 0
Failed:-1
4) Signal Volume PV operation
Usage is the same as the POSIX nameless semaphore, please click this link for details.
A well-known semaphore implements the inter-process mutex function:
#include <stdio.h> #include <semaphore.h> #include <fcntl.h> #include <unistd.h> #include < sys/stat.h> #include <sys/types.h>void printer (sem_t *sem, char *str) {sem_wait (SEM);//signal volume minus one while (*str!= ' n ') {Putchar (*STR); fflush (stdout); Str++;sleep (1);} printf ("\ n"); Sem_post (SEM);//semaphore plus one}int main (int argc, char *argv[]) {pid_t pid;sem_t *sem = Null;pid = Fork ();//Create Process if (pid<0) {//error P Error ("fork error");} else if (PID = = 0) {///Sub-process//is similar to open (), different process as long as the name is the same, then open is the same famous signal volume SEM = sem_open ("Name_sem", o_creat| O_rdwr, 0666, 1); Semaphore value 1if (sem = = sem_failed) {//known semaphore creation failed perror ("Sem_open"); return-1;} char *str1 = "Hello";p rinter (SEM, str1); Print sem_close (SEM); Close the known semaphore _exit (1);} else if (PID > 0) {///parent process//is similar to open (), different process as long as the name is the same, then open is the same famous signal volume SEM = sem_open ("Name_sem", o_creat| O_rdwr, 0666, 1); Semaphore value 1if (sem = = sem_failed) {//known semaphore creation failed perror ("Sem_open"); return-1;} Char *str2 = "World";p rinter (SEM, str2); Print sem_close (SEM); Close the known semaphore wait (PID, NULL); Wait for the child process to end}sem_unlinK ("Name_sem");//delete the named semaphore return 0;}
The results of the operation are as follows:
Well-known semaphores enable inter-process synchronization (Print2 print first, then print1 print):
The PRINT1.C code is as follows:
#include <fcntl.h>/ * for o_* constants */#include <sys/stat.h>/ * for Mode constants */#include < semaphore.h> #include <stdio.h>void print (sem_t *print1, sem_t *print2) {int i = 0;while (1) {sem_wait (print1); i+ +;p rintf ("int print1 i =%d\n", i); Sem_post (Print2);}} int main (int argc, char **argv) {sem_t *print1, *print2;print1 = Sem_open ("Sem_print1", O_creat, 0777, 0); if (sem_failed = = print1) {perror ("Sem_open");} Print2 = Sem_open ("Sem_print2", O_creat, 0777, 1); if (sem_failed = = Print2) {perror ("Sem_open");} Print (print1, print2); return 0;}
The print2.c code is as follows:
#include <fcntl.h>/ * for o_* constants */#include <sys/stat.h>/ * for Mode constants */#include < semaphore.h> #include <stdio.h>void print (sem_t *print1, sem_t *print2) {int i = 0;while (1) {sem_wait (print2); i+ +;p rintf ("in Print2 i =%d\n", i); sleep (1); Sem_post (print1);}} int main (int argc, char **argv) {sem_t *print1, *print2;print1 = Sem_open ("Sem_print1", O_creat, 0777, 0); if (sem_failed = = print1) {perror ("Sem_open");} Print2 = Sem_open ("Sem_print2", O_creat, 0777, 1); if (sem_failed = = Print2) {perror ("Sem_open");} Print (print1, print2); return 0;}
The example code for deleting a known semaphore is as follows:
#include <semaphore.h> #include <stdio.h>void sem_del (char *name) {int ret;ret = Sem_unlink (name); if (ret < 0) {perror ("Sem_unlink");}} int main (int argc, char **argv) {Sem_del ("sem_print1");//delete semaphore file Sem_print1sem_del ("Sem_print2");//delete semaphore file Sem_ Print2return 0;}
The makefile code is as follows:
ALL:GCC sem_del.c-o sem_del-lpthreadgcc print1.c-o print1-lpthreadgcc print2.c-o print2-lpthreadclean:rm sem_del pri Nt1 Print2
when running the program, first remove the known semaphore (Sem_del), then run Print1 and Print2 separately:
For this tutorial sample code download please click here.
Linux system Programming-process synchronization and mutual exclusion: POSIX-known semaphores