The essence of the semaphore is a data manipulation lock, which itself does not have the function of data exchange, but by controlling other
Communication resources (files, external devices) to enable interprocess communication, which is itself an identification of an external resource. Signal
In this process is responsible for the data operation of mutual exclusion, synchronization and other functions.
When a resource is requested to be represented by a semaphore, the process needs to read the value of the semaphore to determine if the resource is available. Greater than 0, the resource can be requested, equals 0, no resources are available, and the process goes to sleep until the resource is available.
When a process no longer uses a semaphore-controlled shared resource, the value of the semaphore is +1, and the value of the semaphore is increased or decreased
Operations are atomic, because the primary function of semaphores is to maintain mutual exclusion of resources or simultaneous access to multiple processes.
In the creation and initialization of the signal volume, the operation is not guaranteed to be atomic.
First, why use the signal volume
To prevent a series of problems that arise when multiple programs access a shared resource at the same time, we need a way to
It can be authorized by generating and using tokens, and at any one time there can be only one critical region that executes thread access code.
A critical region is a code that performs data updates that needs to be executed exclusively. And the semaphore can provide such an interview
Ask the mechanism to make a critical section at the same time only one thread accesses it, that is, the semaphore is used to attune the process
Access to the shared resource. The use of shared memory requires a semaphore.
How the two semaphores work
Since semaphores can only perform two operation waits and send signals, namely P (SV) and V (SV), they behave like this:
P (SV): If the value of SV is greater than 0, it is reduced by 1, and if its value is zero, the execution of the process is suspended.
V (SV): If another process is suspended because it waits for the SV, let it run again, if no process is hung waiting for SV
, add 1 to it.
sem.h 1 #pragma once 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <unistd.h> 5 #include <sys/ipc.h> 6 #include <sys/sem.h> 7 #include <sys/types.h> 8 #define _PATH_ "." 9 #define _PROJ_ID 0X6666 10 union semun { 11 int val; /* value for setval */ 12 struct semid_ds *buf; /* buffer for ipc_stat, ipc_set */ 13 &nBsp; unsigned short *array; /* array for GETALL, SETALL */ 14 struct seminfo *__buf; /* Buffer for ipc_info 15 (linux-specific) */ 16 }; 17 int create_sem_set (int _ Sem_nums); 18 int get_sem_set (); 19 int init_sem_set (int _sem_id,int _ Sem_num,int _init_val); 20 int destroy_sem_set (int sem_id); 21 int p_sem_elem (int _Sem_id,int _sem_num); 22 int v_sem_elem (Int _sem_id,int _sem_num); sem.c 1 #include "sem.h" 2 3 static int Com_create_sem_set (int _sem_nums,int flags) 4 { 5 key_t key=ftok (_path_,_proj_id); 6 if (key<0) 7 { 8 perror ("ftok\n"); 9 return -1; 10 } 11 int _sem_id=semget (Key,_sem_nums,flags); 12 if (_sem_id<0) 13 { 14 Perror ("Semget"); 15 return -1; 16 } 17 return _sem_id; 18 } 19 int create_sem_set (Int _sem_nums) 20 { 21 int flags=ipc_creat| Ipc_excl|0666; 22 return com_create_sem_set (_sem_nums,flags); 23 24 } 25 int get_sem_set (int _sem_nums) 26 { 27 Int flags=ipc_creat; 28 return com_create_sem_set (_sem_nums,flags); 29 30 } 31 int init_sem_set (int _sem_id,int _sem_num,int _ Init_val) 32 { 33 union semun _semnu ; 34 _semnu.val= _init_val; 35 if (Semctl (_sem_id,_sem_num,setval,_semnu)) 36 { 37 perror ("Semctl"); 38 return -1; 39 } 40 return 0; 41 } 42 int destroy_sem_set (int _sem_id) 43 { 44 if (Semctl (_sem_id,0,ipc_rmid)) 45 { 46 perror ("Semctl"); 47 return -1; 48 } 49 return 0; 50 51 } 52 Int com_op_sem_elem (Int _sem_id,int op,int _sem_num) 53 { 54 struct sembuf _sembuf; 55 _sembuf.sem_num=_sem_num; 56 _sembuf.sem_op=op; 57 _sembuf.sem_flg=0; 58 if (Semop (_sem_id , &_sembuf,1)) 59 { 60 perror ("Semop"); 61 return -1; 62 } 63 return 0; 64 65 } 66 int p_sem_elem (Int _sem_id,int _sem_num) 67 { 68 return com_op_sem_elem (_sem_id,-1,_sem_num); 69 } 70 int v_sem_elem (Int _sem_id,int _sem_num) 71 { 72 return com_op_sem_elem (_sem_id,1,_ Sem_num); 73 } test.c: 1 #include " Sem.h " 2 int main () 3 { 4 5 int _ Sem_id=create_sem_set (1); 6 pid_t pid=fork (); 7 init_sem_set (_sem_id,0,1) ; 8 if (pid<0) 9 { 10 perror ("pid"); 11 return -1; 12 } 13 else if (pid==0) 14 { 15 while (1) 16 { 17 int _sem_id= get_sem_set (1); 18 p_sem_elem (_sem_id,0); 19 printf ("a"); 20 sleep (3); 21 printf ("a"); 22 fflush (stdout); 23 sleep (2); 24 v_sem_elem (_sem_id,0); 25 } 26 } 27 28 //destroy_sem_set (_sem _ID);; 29 else 30 { 31 while (1) 32 { 33 p_sem_elem (_sem_id,0); 34 printf ("B"); 35 sleep (5); 36 printf ( "B"); 37 fflush (stdout); 38 sleep (5); 39 v_sem_elem (_sem_id,0); 40 41 } 42 waitpid (pid,null,0); 43 destroy_sem_set (_sem_id); 44 } 45 Return 0; 46 } makefile: 1 sem:sem.c test.c 2 gcc -o [email protected] $^ 3 . phony:clean 4 clean: 5 rm -f sem Results: [[email protected] sem]$ ./ Semaabbaaaabbaaaabbaaaabbaaaabbaaaabbaaaabbaaaabbaaaabbaa^c
This article from "Liveyoung" blog, reproduced please contact the author!
Process Communication (semaphore)