<>1. What is semaphore

   I learned that before System V
IPC Two methods of process communication : Shared memory and message queue are used to exchange and deliver the data of shared area between processes to realize inter process communication , If multiple processes write data to shared memory at the same time, data confusion may occur .

   So is the semaphore System V
IPC A way of communication , And others IPC The difference is that , Semaphores are mainly used to prevent multiple processes from accessing shared data , There are a series of problems such as competition , Semaphores are used for process synchronization .

linux There are two semaphores :

Kernel semaphore , It is generally controlled by the kernel

User semaphore , The user semaphore is divided into POSIX Sum of semaphores System V Semaphore

Here we mainly discuss System V Semaphore .

<>2. Semaphore IPC object

For semaphores , The system also maintains one in kernel space IPC object , Namely semid_ds structural morphology , The specific definitions are as follows :
struct semid_ds { struct ipc_perm sem_perm; /* Operation authority of semaphore set */ struct sem *
sem_base; /* Pointer to an array of semaphores , Each semaphore in the current semaphore set corresponds to one of them sem Array elements of structure */ ushort sem_nsems; /*
sem_base Number of arrays among ushort by unsigned short type */ . . . };
You can see this from the top IPC The main objects are sem_perm Structure and sem_base structural morphology , among sem_perm Structs are used to manipulate semaphores , and sem_base A struct is an array of semaphores .

sem_base The maximum number of 25 Elements , Each element is a semaphore , For easy understanding , It can be considered as a set of semaphores , That is to say, a semaphore set has at most only 25 Semaphores . And the data type is struct

Schematic diagram of semaphore set kernel :

Here are the semaphores for kernel maintenance struct sem Structure part information :
struct sem { int semval; /* The current value of the semaphore */ int sempid; /* The process of the last operation pid */ struct
list_head sem_pending; /* pending single-sop operations */ . . . };
Semaphores can be understood as something like a counter , It can control the process's access to resources , When a process is consuming resources , The semaphore will decrease , When the process releases resources , The semaphore will increase . You can use functions to control , This function either performs a complete operation , Or not at all , This is atomic manipulation ( Atomic operation means that the operation is a complete operation , It is indivisible ). If you run out of resources , The counter counts down to 0, At this point, if the process accesses the resource again, it will block .

<>3. Create or get semaphores —semget function

function semget It is mainly used to create and obtain ipc Kernel object ( Semaphore ), Return at the same time ipc Object identifier id.
int semget(key_t key, int nsems, int semflg);
Return value : Successful return IPC object ( Semaphore ) Identifier for id, Failure Return -1.

Parameter description :
   key: The usage is the same as that learned before IPC( Shared memory , Message queuing ) Key value of key It's the same .

   nsems: Indicates the number of semaphores you want to create , If the semaphore has been created , To get which semaphore, you only need to transmit the index number of the semaphore .

   semflg: Of the specified semaphore IPC_CREAT,IPC_EXCL Permission combination .semflg =
IPC_CREAT, If the signal does not exist, a semaphore is created , Otherwise, get it .IPC_EXCL Only when the semaphore does not exist , New semaphores are created , Otherwise, something goes wrong .

<>4. Set or get semaphore value —semctl function

semctl Function is mainly used to set or get semaphore value
int semctl(int semid, int semnum, int cmd, union semun);
Return value description : A positive number was returned successfully , Failure Return -1 And set errno

Parameter description :
   semnum: Is the semaphore in the specified signal set , Semaphore number from 0 start

cmd: Use the command to set or get semaphore values , about IPC_STAT,IPC_SET,IPC_RMID The three options are described earlier , These three options are operations semun In the Consortium buf Member's .

The following are options for getting or setting semaphores :

* SETVAL: It is usually used to set a semaphore value , adopt val set up
* SETALL: Used to set all semaphore values , adopt array set up
* GETVAL : Used to obtain a semaphore value , Store in val
* GETALL : Used to get the value of all semaphores , Store in array
semun: It is used to save the semaphore value to be set or to save the acquired semaphore value .semun It's a consortium . So this parameter can pass in a short An array of types , You can also pass in one int Type single semaphore , Or a semid_ds The set of semaphores of type

<>5. Request or release semaphore —semop function

semop Function is mainly used to request or release semaphore resources
int semop(int semid, struct sembuf *sops, unsigned nsops);
Return value description : Successful return 0, Failure Return -1 set up errno

Parameter description :
   semid:IPC object ( Semaphore set ) identifier id

   sops: Is an array of pointing semaphore structures , Array elements are sembuf
structural morphology , This structure encapsulates the request or return semaphore , And operate that semaphore , And the behavior characteristics of operating semaphore .

   nsops: Indicates the semaphore sembuf Structure array size , That is, the number of array elements .
struct sembuf { unsigned short sem_num; /* Semaphore subscript to operate */ short sem_op; /* > 0
Number of returned resources ,< 0 Number of requested resources */ short sem_flg; /* Optional , Behavior of operation */ }
sem_num: Which signal to represent

   If sem_op > 0, Indicates that the process releases semaphore controlled resources , Then the semaphore plus sem_op Value of .

   If sem_op < 0, Indicates process application
Resources for semaphore control , Then the signal is subtracted sem_op Absolute value of , If the semaphore value is less than sem_op Absolute value of ( That is, the process application semaphore control resources are insufficient ). If specified IPC_NOWAIT, be semop Error return EAGAIN, If not specified IPC_NOWAIT, Then block wait .

   If sem_op = 0, Indicates that the process is blocking and waiting , Until the semaphore value is 0, Then the function returns . If the semaphore is always not 0 value , If specified sem_flg =
IPC_NOWAIT, Error return EAGIN. If not specified sem_flg = IPC_NOWAIT, Then the process blocks and waits for the following events to occur :

* Until the semaphore value is 0
* Remove this signal from the system , Process unblocking , Then the function returns an error
* The process caught a signal , And return from the signal processing function , Process unblocking , Then the function returns an error
sem_flg: Optional , It is generally 0 .

* sem_flg = IPC_NOWAIT, Whether the requested resource is available or not , Return immediately . If there are no resources ,errno Set to EAGAIN.
* sem_flg =
SEM_UNDO, Indicates when the process ends , The corresponding operation will be cancelled . in other words , If the SEM_UNDO, When the process exits without releasing the shared resources , The kernel will replace the release .

<>6. Semaphore operation example
#include <sys/types.h> #include <sys/sem.h> #include <sys/ipc.h> #include
<stdlib.h> #include <stdio.h> #include <errno.h> void print_sem(int semid) {
// Print semaphore int ret; unsigned short arr2[2] = {0}; ret = semctl(semid , 2 , GETALL ,
arr2); if(ret < 0){ perror("semtcl error:"); } printf("sem1 = %d , sem2 = %d\n"
, arr2[0] , arr2[1]); } int main(void) { int ret; int semid = 0; key_t key =
0x00112233; // Create signal set ,2 Signals semid = semget(key , 2 , IPC_CREAT | IPC_EXCL | 0664);
if(semid < 0){ perror("semget error:"); } // View created semaphores IPC object system("ipcs -s");
puts("----------------------"); // The value of the first semaphore is 1, The value of the second semaphore is 2 unsigned short arr1[2] =
{1 , 2}; // adopt array Set two semaphores ret = semctl(semid , 0 , SETALL , arr1); if(ret < 0){
perror("semtcl error:"); } // Means request No 2 Semaphores , request 2 Resources struct sembuf buf1 = {1 , -2 , 0}
; semop(semid , &buf1 , 1); // Print semaphore print_sem(semid); // Release No 2 Semaphores , release 2 Resources struct
sembuf buf2= {1 , 2 , 0}; semop(semid , &buf2 , 1); // Print semaphore print_sem(semid);
// Delete semaphore set semctl(semid , 0 , IPC_RMID); puts("----------------------");
// View semaphore IPC object system("ipcs -s"); return 0; }

Program running results :

©2019-2020 Toolsou All rights reserved,
Thoughts on multi tenant system JQ get request Splicing url parameter ( query criteria ) exercises 11-5 Output string at specified position 415 Status code to background error TypeScript Data types in is enough vue Value transfer between parent-child and non parent-child components python Short circuit logic in ElementUI In the select Of label value SpringBoot JpaRepository Database addition, deletion, modification and query css Basics 2:flex Multi row layout with gaps