Linux semaphore practices (1) and linux semaphore practices
Process Synchronization and mutex
Sequential program and concurrent program features
Sequential Program |
Concurrent program |
Sequence |
Sharing |
Closed: (closed runtime environment) |
Concurrency |
Certainty |
Randomness |
Reproducibility |
|
Process mutex
Because various processes need to share resources and some resources need to be mutually exclusive, the competition between processes uses these resources. The process is mutually exclusive.
Some resources in the system can only be used by one process at a time. Such resources are called critical resources or mutually exclusive resources.
The program segment that involves mutex Resources in the process is called the critical section.
Mutex examples
Note: if the number of votes X = 1 at this time, process A and process B both obtain the critical resource X and execute X --, then X <0 appears, this is definitely unreasonable, and the number of votes cannot be less than 0;
Process Synchronization
Process Synchronization means that multiple processes need to work together to complete a task.
Synchronization example
Note: Only when the driver P1 cooperates with the conductor P2 can the ticket sales process be completed.
Deadlock generation and Removal
A deadlock is a phenomenon in which multiple processes wait for each other's resources, but do not release their own resources before obtaining the other's resources. If all processes are waiting for an impossible event, the process will be deadlocked.
Conditions for deadlock
1) mutex Conditions
A process schedules its use of resources, that is, a resource is only occupied by a process within a period of time.
2) request and retention conditions
When a process is blocked due to a resource request, the obtained resources are retained.
3) conditions of deprivation
Resources obtained by a process cannot be deprived before they are used up. You can only release them when they are used up.
4) loop wait Conditions
Each process forms a closed ring chain, and each process waits for the resources occupied by the next process.
Deadlock Prevention Measures
One-time resource allocation (damage request and retention conditions)
Deprivation of resources (damage to the conditions of deprivation)
Orderly resource allocation (destruction of cyclic waiting conditions)
Deadlock Avoidance
Several deadlock prevention policies can seriously damage system performance. Therefore, when avoiding deadlocks, we must apply weak restrictions to achieve satisfactory system performance.
Because the process is allowed to dynamically apply for resources in a deadlock-free policy. Therefore, the system calculates the security of resource allocation in advance before allocating resources. If this allocation does not cause the system to enter an insecure state, the resource will be allocated to the process; otherwise, the process will wait. The most representative Deadlock Avoidance algorithm is the bankers algorithm.
Semaphores
Semaphores and P and V primitives proposed by Dijkstra (dijela)
Mutual Exclusion: P and V are in the same process.
Synchronization: P and V are in different processes.
Signal Value Meaning
S> 0: S indicates the number of available resources.
S = 0: no available resources and no waiting process
S <0: | S | Number of processes in the waiting queue
PV operation
Struct semaphore {int value; pointer_PCB queue;} // P primitive P (s) {-- s. value; if (s. value <0) // indicates there are no idle resources {set the current process to blocking state; insert the PCB of the current process into the corresponding blocking queue s. end of queue;} // V primitive V (s) {++ s. value; if (s. value <= 0) // indicates that a process is in the blocking status {wake up the blocked queue s. A waiting process in the queue, set it to the ready state; insert it into the ready queue ;}}
Semaphore API
Linux maintains the data structure for semaphores
struct semid_ds{ struct ipc_perm sem_perm; /* Ownership and permissions */ time_t sem_otime; /* Last semop time */ time_t sem_ctime; /* Last change time */ unsigned long sem_nsems; /* No. of semaphores in set */};
Semaphores
#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h> int semget(key_t key, int nsems, int semflg); int semctl(int semid, int semnum, int cmd, ...);int semop(int semid, struct sembuf *sops, unsigned nsops);
Semget Function
Function: used to create and access a semaphore set
Prototype
int semget(key_t key, int nsems, int semflg);
Parameters
Key: Signal Set key)
Nsems: Number of semaphores in a signal set
Semflg: consists of nine permission marks. Their usage is consistent with the mode mark used when creating a file.
Return Value:
A non-negative integer is returned, that is, the ID code of the signal set;-1 is returned if the signal set fails.
// Practice int main () {int semid = semget (0x12345670,1, 0666 | IPC_CREAT); if (semid =-1) {if (errno = EEXIST) {err_exit ("EEXIST");} else {err_exit ("semget error") ;}} else {cout <"semget OK" <endl ;} return 0 ;}
Shmctl Function
Function: used to control the semaphore set.
Prototype
int semctl(int semid, int semnum, int cmd, ...);
Parameters
Semid: ID of the Signal Set returned by semget
Semnum: the serial number of the semaphores in the signal set.
Cmd: the action to be taken (the value is as follows)
The last parameter varies with the command.
Return Value:
0 is returned for success;-1 is returned for failure.
Man-page semctl() performs the control operation specified by cmd on the System V semaphore set identified by semid, or on the semnum-th semaphore of that set. (The semaphores in a set are numbered starting at 0.) This function has three or four arguments, depending on cmd. When there are four, the fourth has the type union semun. The calling program must define this union as follows:union semun{ int val; /* Value for SETVAL */ struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ unsigned short *array; /* Array for GETALL, SETALL */ struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */};
// Practice: SETVALunion mySemUn {int val; // Value for SETVAL // struct semid_ds * buf; // Buffer for IPC_STAT, IPC_SET // unsigned short * array; // Array for GETALL, SETALL // struct seminfo * _ buf; // Buffer for IPC_INFO (Linux-specific) //}; int main () {int semid = semget (0x12345670,1, 0666 | IPC_CREAT); if (semid =-1) {err_exit ("semget error");} union mySemUn setValue; setValue. val = 15764; if (semctl (semi D, 0, SETVAL, setValue )! = 0) {err_exit ("semctl SETVAL error");} int returnValue = semctl (semid, 0, GETVAL, 0 ); cout <"returnValue =" <returnValue <endl; return 0 ;}
Semop Function
Function: used to manipulate a semaphore set.
Prototype
int semop(int semid, struct sembuf *sops, unsigned nsops);
Parameters
Semid: The ID code of the semaphore, that is, the return value of the semget function.
Sops: a pointer to a structure array.
Nsops: Number of semaphores
Return Value:
0 is returned for success;-1 is returned for failure.
// Man-page sample Code struct sembuf sops [2]; int semid;/* Code to set semid omitted */sops [0]. sem_num = 0;/* Operate on semaphore 0 */sops [0]. sem_op = 0;/* Wait for value to equal 0 */sops [0]. sem_flg = 0; sops [1]. sem_num = 0;/* Operate on semaphore 0 */sops [1]. sem_op = 1;/* Increment value by one */sops [1]. sem_flg = 0; if (semop (semid, sops, 2) =-1) {perror ("semop"); exit (EXIT_FAILURE );}
For the sembuf struct, refer to the following:
struct sembuf{ unsigned short sem_num; /* semaphore number */ short sem_op; /* semaphore operation */ short sem_flg; /* operation flags */};
Sem_num is the number of the semaphore (starting from 0 ).
Sem_op is the value added or subtracted from a PV operation of the semaphore. Generally, only two values are used. One value is "-1", that is, the P operation. Wait until the semaphore becomes available; the other is "+ 1", that is, the V operation, and the semaphore has become available;
The two sem_flag values are IPC_NOWAIT or SEM_UNDO.