Signal Volume---Sem_lock

Source: Internet
Author: User

The signal Volume SEM -----is responsible for inter-process mutual exclusion, synchronization and other functions----metering a number of resources

1, the essence is a data operation Lock ( counter ), which itself does not have the function of data exchange, but by controlling other communication resources (files, external devices) to achieve inter-process communication, which itself is only an external resource identification.

Semaphores request resources in a semaphore set.


Critical resources: Resources that can be accessed by multiple processes

Critical section: A section of code that accesses critical resources

Mutex: Exclusive Critical resource

Synchronization: Run with sequential processes, (most of them) built on mutually exclusive cases

P Operation: Check semaphore, not 0 semaphore-1, reverse (0), Suspend---request resource

V Operation: Check the signal volume, 0 signal volume +1 and wake up, enter the critical section; (!=0), Hang

int semop (int semid, struct sembuf *sops, unsigned nsops);

The operation of the signal volume P, V and increase or decrease can guarantee atomicity, and its creation and initialization, it is not guaranteed.

2. Union and Structure:

Union Semun {int val;//values used by struct semid_ds *buf;//Ipc_stat, ipc_set using buffer unsigned short *array;//GETALL, SETALL used by the array struct seminfo *__buf; Ipc_info (Linux-specific) using buffers};
struct sembuf{unsigned short sem_num;            /* Semaphore number */short sem_op;           /* Semaphore operation */short SEM_FLG; /* Operation flags * *};

3,Sem_undo :

At the end of the program (whether normal or unhealthy), ensure that the signal value is reset to the value before the SEMOP () call. This is done to prevent the program from unlocking the locked resource at the end of an exceptional situation, causing the resource to be locked forever.

(1)Semop operation: It is based on three possible values for each specified SEM_OP operation: positive, negative, or 0.

1. If Sem_op is a positive number, its value is added to Semval, which corresponds to releasing a resource controlled by a semaphore.

If the Sem_undo flag is specified, the value of Sem_op is lost from the Semadj value of the corresponding semaphore.

2. If Sem_op is negative , then the caller wants to wait for semval to become greater than or equal to the absolute value of sem_op. This corresponds to the allocation of resources.

If the semval is greater than or equal to the absolute value of sem_op, then the absolute value of Sem_op is lost from the Semval.

If the Sem_undo flag is specified, the absolute value of the sem_op is added to the Semadj of the corresponding semaphore.

3. If Sem_op equals 0, the program must have read permission to wait until a process has occurred.


(2) Precautions for use:

      • Using the Sem_undo flag will record the operation of the semaphore in the Semadj, and if the program exits, the value of Semadj will be added to the semval.

      • Sem_undo needs to be paired, and if it is not paired, the use of Semadj may cause an SEMADJ overflow and an error occurs.

      • All resources (semaphores, etc.) need to be initialized at the start of the program, and various resources (semaphores/shared memory, etc.) need to be cleaned up when exiting.


4. Example: Signal lock

Comm.h

#pragma  once#include<stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/ ipc.h> #include <sys/sem.h> #include <sys/wait.h> #include <errno.h> #define  _PATH_  '. ' #define  _PROJ_ID_ 0x6666union semun{int val; //  The value struct semid_ds * Buf; // ipc_stat, ipc_set  use buffer unsigned short *array; // getall, SETALL   Arrays used by Struct seminfo *__buf; // ipc_info (Linux-specific)   using buffer};static int  Comm_sem_set (int _sem_num,int flags); Int create_sem_set (int _sem_num); int get_sem_set (Int _sem_num); Int init_sem_set (Int _sem_id,int _seq_num,int _init_val);static  Int comm_sem_op (INT&NBSP;_SEM_ID,INT&NBSP;_SEQ_NUM,INT&NBSP;_OP); Int p_sem_elem (Int _sem_id,int  _seq_num); Int v_sem_elem (Int _sem_id,int _seq_num); Int destroy_sem_set (Int _sem _ID);

//comm.c

#include   "comm.h" Static int comm_sem_set (int _sem_num,int flags) {Key_t _key=ftok ((char*) _path_,_proj_id_); if (_key < 0) {perror ("Ftok"); return -1;} Int sem_id=semget (_key,_sem_num,flags); if (sem_id < 0) {perror ("Semget"); return -1;} return sem_id;} Int create_sem_set (int _sem_num) {int flags=ipc_creat| Ipc_excl|0666;return comm_sem_set (_sem_num,flags);} Int get_sem_set (int _sem_nums) {int flags=ipc_creat;return comm_sem_set (_sem_nums,flags);} Int init_sem_set (int _sem_id,int _seq_num,int _init_val) {Union semun _un;_un.val =_init_val;if (Semctl (_sem_id,_seq_num,setval,_un)  < 0) {perror ("Semctl"); return -1;} return 0;} Static int comm_sem_op (int _sem_id,int _seq_num,int _op) {Struct sembuf _sem _buf[1];_sem_buf[0].sem_num=_seq_num;_sem_buf[0].sem_op=_op;if (Semop (_sem_id,_sem_buf,1)  < 0) { Perror("Semop"); return -1;} return 0;} Int p_sem_elem (int _sem_id,int _seq_num) {return comm_sem_op (_sem_id,_seq_num,-1);} Int v_sem_elem (int _sem_id,int _seq_num) {return comm_sem_op (_sem_id,_seq_num,1);} Int destroy_sem_set (int _sem_id) {if (Semctl (_sem_id,0,ipc_rmid,null)  < 0) {perror ("Semctl "); return -1;} return 0;}

(1) Pre-lock--->

Sem_lock.c

#include "comm.h" int main () {pid_t id=fork (); if (ID < 0) {perror ("fork"); return-1;} else if (id = = 0)//child{while (1) {printf ("a"), sleep (1), fflush (stdout);p rintf ("a"), Sleep (3); fflush (stdout);}} Else//father{while (1) {printf ("B"), Sleep (1), fflush (stdout);p rintf ("B"), Sleep (2); fflush (stdout);} Waitpid (id,null,0);} return 0;}

Operation Result:

650) this.width=650; "src=" http://s1.51cto.com/wyfs02/M01/7F/03/wKiom1cPhMTxuibXAAAaA3cGKLs502.jpg "title=" initial. jpg "alt=" Wkiom1cphmtxuibxaaaaa3cgkls502.jpg "/>

(2) after lock--->

Sem_lock.c

#include "comm.h" int main () {int Sem_id=create_sem_set (1), Init_sem_set (sem_id,0,1);p id_t id=fork (), if (ID < 0) { Perror ("fork"); return-1;} else if (id = = 0)//child{int _sem_id=get_sem_set (1), while (1) {P_sem_elem (_sem_id,0);p rintf ("A"), sleep (1); Fflush ( STDOUT);p rintf ("A"); sleep (3); fflush (stdout); V_sem_elem (_sem_id,0);}} Else//father{int _sem_id=get_sem_set (1); while (1) {P_sem_elem (_sem_id,0);p rintf ("B"); sleep (1); fflush (stdout); printf ("B"); Sleep (2); fflush (stdout); V_sem_elem (_sem_id,0);} Waitpid (id,null,0);} Destroy_sem_set (sem_id); return 0;}

Operation Result:

650) this.width=650; "src=" Http://s2.51cto.com/wyfs02/M00/7F/03/wKiom1cPhOLR290SAAAZLoiT-c4382.jpg "title=" The front ff removes the. jpg "alt=" wkiom1cpholr290saaazloit-c4382.jpg "/>

This article is from the "Flower Open Shore" blog, please be sure to keep this source http://zxtong.blog.51cto.com/10697148/1763911

Signal Volume---Sem_lock

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.