When multiple process tables access a resource on the system at the same time, such as writing a record of a database at the same time, or altering a file at the same time, you need to consider the synchronization problem in the city to ensure that only one process at any one time has exclusive access to resources.
Usually. The code for the program's access to shared resources is only a very short paragraph. You're the one. The code raises the race condition between processes. We call this code a critical section, or a critical section.
A semaphore is a special variable that only takes natural numbers and supports only two operations: wait and signal (signal), which are more commonly called P and V operations.
If there is a semaphore SV. Then to it the P, v operation meanings are as follows:
L P (SV), assuming that the value of SV is greater than 0. Reduce it by 1: The value of the SV is assumed to be 0. The run of the process is suspended.
L V (SV), assuming that there are other processes waiting for the SV two to hang, then the star of the change. If not, the SV is added 1.
The semaphore API mainly consists of 3 system calls: Semget, Semop, and Semctl.
They are designed to operate a set of semaphores, the set of semaphores, rather than a single semaphore.
#include <sys/sem.h>int semget (key_t key, int num_sems, int sem_flags), int semop (int sem_id, struct sembuf *sem_ops, size_t num_sem_ops); int semctl (int sem_id, int sem_num, int command, ...);
L semget function Call creates a new semaphore set or gets a semaphore that exists. The key parameter is a key value used to identify a globally unique semaphore set. Just as the file name globally uniquely identifies a file.
The process to communicate through semaphores requires the same key value to be used to create or obtain the semaphore.
Num_sems parameters Specifies the number of semaphores in the semaphore set to be created or obtained. Assume that the semaphore is created. The value must be specified; If you get the semaphore that already exists, you can set it to 0
The Sem_flags parameter specifies a set of flags. Its low-end 9 bits are the permission of the semaphore, and its format and meaning are the same as the system call to open's mode parameter. We are able to do a bitwise "or" operation with the IPC_CREAT flag, even if the semaphore exists at this time. Semget also will not error. We can also use the ipc_creat and IPC_EXCL flags to ensure that a new set of unique semaphore sets is created, and if the semaphore is present, Semget returns an error and sets errno to Eexist.
Semget returns a positive integer when the call succeeds, which is the identifier of the semaphore set, returns 1 on failure, and sets the errno
The L semop function Changes the value of the semaphore. Run P and V operations
The sem_id parameter is the semaphore set identifier returned by the Semget call to specify the set of target semaphores to be manipulated.
The Sem_ops parameter points to an array of SEMBUF structures, such as the following:
struct sembuf{ unsigned short int sem_num; short int sem_op; short int sem_flg;};
Sem_num is the number of semaphores in the semaphore set, like an array, starting from 0.
SEM_OP Specifies the action type, with an optional value of positive integer, 0, negative integer. Each type of operational behavior is also affected by SEM_FLG.
The optional values for SEM_FLG are ipc_nowait, Sem_undo. Ipc_nowait means that Semop calls return immediately, similar to non-clogging, regardless of the success of the semaphore operation.
Sem_undo refers to canceling an ongoing SEMOP operation when the process exits.
The Num_sem_ops parameter specifies the number of operations to run, that is, the number of sem_ops in the array. Semop each member of an array is run sequentially in the order of arrays, which is an atomic operation.
SEMOP returns 0 on success, returns 1 on failure and sets errno
The L semctl function agrees that the caller directly operates on the semaphore
The sem_id parameter is the semaphore set identifier returned by the Semget call to specify the set of semaphores to be manipulated.
The Sem_num parameter specifies the number of semaphores to be manipulated in the semaphore set.
Command parameters specify the commands to run.
Some orders require a 4th number of parameters.
It is custom-defined by the user. However, the recommended format is given in sys/sem.h:
Union semun{ int val; For setval command struct semid_ds *buf; For Ipc_stat and Ipc_set commands unsigned short *array; For GetAll and SetAll command struct seminfo *__buf; for Ipc_info commands};
The return value of Sem_ctl success depends on the command parameter, which returns 1 on failure and sets the errno
Special Key Values ipc_private ( key parameter of the Semget function )
Semget callers can give them Key the parameters pass a special key value ipc_pricate ( Its value is 0) . This allowsthesemget to create a new semaphore regardless of whether the semaphore already exists. The semaphore created with this key value is not private to the process, as other names claim. Other processes, especially sub-processes, have methods to access the semaphore
Demo sample using the Ipc_private program
#include <sys/sem.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include < sys/wait.h> #define ERR_SYS (msg) do {perror (msg); exit ( -1),} while (0) union semun{int val;struct Semid_ds *buf;unsigne d Short int *array;struct seminfo * __BUF;}; void PV (int sem_id, int op) {struct Sembuf sem_b;sem_b.sem_num = 0;sem_b.sem_op = OP;SEM_B.SEM_FLG = Sem_undo;semop (sem_id, &sem_b, 1);} int main (void) {int sem_id = Semget (ipc_private, 1, 0666);/* The semaphore set size is 1 */union semun sem_un;sem_un.val = 1;/* The value is 2 o'clock, which indicates the ability to At the same time two processes run P operations (i.e. 1 operations) */semctl (sem_id, 0, Setval, Sem_un); /* Operate the first signal in the semaphore set */pid_t pid = fork (), if (PID < 0) Err_sys ("fork"), else if (PID = = 0) {PV (sem_id,-1);p rintf ("Child get t He sem and would sleep 5s.\n "); Sleep (5);p V (sem_id, 1); exit (0);} ELSE{PV (sem_id,-1);p rintf ("Parent get the SEM and would sleep 5s.\n"); Sleep (5);p V (sem_id, 1);} Waitpid (PID, NULL, 0); Semctl (sem_id, 0, Ipc_rmid, sem_un); return 0;}
References:
1, "Linux High Performance Server programming," The 13th chapter multi-process programming/signal Volume
2, Linux multi-process programming
Linux interprocess communication-semaphore