当前位置:网站首页>Process communication - semaphore
Process communication - semaphore
2022-07-03 09:37:00 【zhyg_ three hundred and twenty-one】
1.sem
- struct sem {
- short sempid; /* pid of last operation */
- ushort semval; /* current value */
- ushort semncnt; /* num procs awaiting increase in semval */
- ushort semzcnt; /* num procs awaiting semval = 0 */
- };
sem_pid The member saves the process of the last semaphore operation pid.
sem_semval Members store the count value of semaphores .
sem_semncnt The member holds the number of processes waiting to use resources .
sem_semzcnt Members save the number of processes waiting for resources to be completely idle .
2.semun
semun The consortium is in senctl() Use in a function , Provide senctl() Information required for operation .
- union semun {
- int val; /* value for SETVAL */
- struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
- ushort *array; /* array for GETALL & SETALL */
- struct seminfo *__buf; /* buffer for IPC_INFO */
- void *__pad;
- };
3.sembuf
sembuf The structure is semop() Function is used to define basic operations on semaphore objects
- struct sembuf {
- unsigned short sem_num; /* semaphore index in array */
- short sem_op; /* semaphore operation */
- short sem_flg; /* operation flags */
- };
sem_num The member is the sequence number of the semaphore receiving the operation in the semaphore array ( The array subscript ).
sem_op Member defines the operation to be performed ( It can be positive 、 Negative and zero ).
sem_flg It is a sign of controlling operation behavior .
4.semid_qs
and msgqid_ds similar ,semid_qs Structure is used by the system to store information about each semaphore object .
- struct semid_ds {
- struct ipc_perm sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t sem_otime; /* last semop time */
- __kernel_time_t sem_ctime; /* last change time */
- struct sem *sem_base; /* ptr to first semaphore in array */
- struct sem_queue *sem_pending; /* pending operations to be processed */
- struct sem_queue **sem_pending_last; /* last pending operation */
- struct sem_undo *undo; /* undo requests on this array */
- unsigned short sem_nsems; /* no. of semaphores in array */
- };
among ,
sem_perm Members store the access rights of semaphore objects and other information .
sem_otime Members saved the last semop() Time of operation .
sem_ctime The member saves the time when the semaphore object was last changed .
sem_base The pointer stores the starting address of the semaphore array .
sem_pending The pointer saves the operation that has not been carried out .
sem_pending_last The pointer holds the last operation that has not been performed .
sem_undo Members saved undo The number of requests .
sem_nsems Member holds the number of members of the semaphore array .
Related functions
1.semget()
Use semget() Function to create a new semaphore object or get the identifier of an existing object .
system call : semget()
Function declaration : int semget(key_t key,int nsems,int semflg);
Return value : semaphore set IPC identifier on success
- int open_semaphore_set(key_t keyval, int numsems)
- {
- int sid;
- if(!numsems) return(-1);
- if((sid=semget(keyval,numsems,IPC_CREAT|0660))==-1)
- {
- return(-1);
- }
- return(sid);
- }
2.semop()
Use this function to change the state of each semaphore in the semaphore object .
system call : semop()
Function declaration : int semop(int semid, struct sembuf *sops, unsigned int nsops);
Return value : 0 on success (all operations performed)
The first parameter semid Is the identifier of the semaphore object to be operated .
The second parameter sops yes sembuf Array of , It defines the semop() The sequence of operations to be performed by the function .
The third parameter nsops preserved sops Length of array , That is to say semop() The number of operations that the function will perform .
3.semctl()
And message queues msgctl() Function similar to ,semctl() Function is used to directly control the semaphore object
system call : semctl()
Function declaration : int semctl(int semid, int semnum, int cmd, union semun arg);
Return value : positive integer on success
Comparing the parameters of these two functions, we find some subtle differences . First , Because the semaphore object is actually a collection of multiple semaphores rather than a single individual , So when operating , It is not only necessary to specify the identifier of the object , You also need to use the sequence number of semaphores in the set to specify specific semaphore individuals .
Both functions have cmd Parameters , Specifies the specific operation of the function . however , and msgctl() Compared to the function , semctl() Functions can do much more :
IPC_STAT Get semaphore object semid_ds structural information , And store it in arg Parameters in buf The pointer returns .
IPC_SET use arg Parameters in buf To set the... Of the semaphore object semid_ds structural information . Just like the message queue object , Only a few parameters can be set by this function .
IPC_RMID Delete semaphore object from memory .
GETALL Get the values of all semaphores in the semaphore object , And store it arg In the parameter array Array returns .
GETNCNT Returns the number of processes waiting to use a semaphore controlled resource .
GETPID Returns the last call to a semaphore semop() The process of the function pid.
GETVAL Return the value of a semaphore of the object .
GETZCNT Returns the number of processes waiting for the resources controlled by a semaphore to be fully used .
SETALL use arg Parameters in array Array value to set the value of each semaphore in the object .
SETVAL use arg Parameters in val Member to set the value of a semaphore in the object .
- int get_sem_val(int sid, int semnum)
- {
- return(semctl(sid,semnum,GETVAL,0));
- }
- void init_semaphore(int sid, int semnum, int initval)
- {
- union semun semopts;
- semopts.val=initval;
- semctl(sid, semnum, SETVAL, semopts);
- }
In message queues and semaphore objects , There are IPC_STAT and IPC_SET The operation of . However, due to the different types of passed parameters , Caused the difference in their use . stay msgctl() Function ,IPC_STAT The operation is simply to put the kernel msgqid_ds junction
The address of the structure is given buf Parameters ( It's a pointer ). And in the semctl() Function , IPC_STAT The operation is to semid_ds Copy the contents of to arg Parametric buf In the memory indicated by the member pointer . therefore , The following code will generate errors , and msgctl() Functional
Similar code does not :
- void getmode(int sid)
- {
- int rc;
- union semun semopts;
- /* The following statement will produce errors */
- if((rc=semctl(sid, 0, IPC_STAT, semopts))==-1)
- {
- perror("semctl");
- }
- printf("Pemission Mode were %o/n", semopts.buf->sem_perm.mode);
- return;
- }
- void getmode(int sid)
- {
- int rc;
- union semun semopts;
- struct semid_ds mysemds;
- /* to buf The pointer prepares a piece of memory */
- semopts.buf=&mysemds;
- /* Now? OK 了 */
- if((rc=semctl(sid, 0, IPC_STAT, semopts))==-1)
- {
- perror("semctl");
- }
- printf("Pemission Mode were %o/n", semopts.buf->sem_perm.mode);
- return;
- }
example :
- semtool.c
- #include <stdio.h>
- #include <ctype.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/sem.h>
- #define SEM_RESOURCE_MAX 1 /*Initial value of all semaphores*/
- void opensem(int *sid, key_t key);
- void createsem(int *sid, key_t key, int members);
- void locksem(int sid, int member);
- void unlocksem(int sid, int member);
- void removesem(int sid);
- unsigned short get_member_count(int sid);
- int getval(int sid, int member);
- void dispval(int sid,int member);
- void changemode(int sid, char *mode);
- void usage(void);
- int main(int argc, char *argv[])
- {
- key_t key;
- int semset_id;
- if(argc == 1) usage();
- /*Create unique key via call to ftok()*/
- key=ftok(".",'s');
- switch(tolower(argv[1][0]))
- {
- case 'c':
- if(argc!=3)usage();
- createsem(&semset_id, key, atoi(argv[2]));
- break;
- case 'l':
- if(argc!=3) usage();
- opensem(&semset_id, key);
- locksem(semset_id, atoi(argv[2]));
- break;
- case 'u':
- if(argc!=3) usage();
- opensem(&semset_id, key);
- unlocksem(semset_id, atoi(argv[2]));
- break;
- case 'd':
- opensem(&semset_id,key);
- removesem(semset_id);
- break;
- case 'm':
- opensem(&semset_id, key);
- changemode(semset_id, argv[2]);
- break;
- default:
- usage();
- }
- return(0);
- }
- void opensem(int *sid, key_t key)
- {
- /*Open the semaphore set ---do not creat!*/
- if((*sid=semget(key, 0 , 0666)==-1)
- {
- printf("Semaphore set does not exist!/n");
- exit(1);
- }
- }
- void createsem(int *sid, key_t key, int members)
- {
- int cntr;
- union semun semopts;
- if(members > SEMMSL){
- printf("Sorry,max number of semaphores in a set is %d/n",SEMMSL);
- exit(1);
- }
- printf("Attempting to create new semaphore set with %d members/n",members);
- if((*sid=semget(key, members, IPC_CREAT|IPC_EXCL|0666))==-1)
- {
- fprintf(stderr,"Semaphore set already exist!/n");
- exit(1);
- }
- semopts.val= SEM_RESOURCE_MAX;
- /*Initialize all members(could be done with SETALL)*/
- for(cntr=0;cntr<members;cntr++)
- {
- semctl(*sid, cntr, SETVAL, semopts);
- }
- }
- void locksem(int sid, int member)
- {
- struct sembuf sem_lock={0, -1, IPC_NOWAIT};
- if(member <0 ||member>(get_member_count(sid) -1))
- {
- fprintf(stderr,"semaphore member %d out of range/n", member);
- return;
- }
- /*Attempt to lock the semphore set*/
- if(!getval(sid, member))
- {
- fprintf(stderr,"Semaphore resources exhausted (no lock)/n")
- exit(1);
- }
- sem_lock.sem_num =member;
- if((semop(sid, &sem_lock, 1)==-1)
- {
- fprintf, "Lock faild/n");
- exit(1);
- }
- else
- printf("Semaphore resources decremented by one (locked)/n");
- dispval(sid ,member);
- }
- void unlocksem(int sid, int member)
- {
- struct sembuf sem_unlock={member, 1, IPC_NOWAIT};
- int semval;
- if(member<0 || member>(get_member_count(sid)-1))
- {
- fprintf(stderr,"Semaphore member %d out of range/n",member);
- return;
- }
- /*Is the semaphore set locked? */
- semval =getval(sid, member);
- if(semval==SEM_REOURSE_MAX){
- fprintf(stderr, "Semaphore not locked!/n");
- exit(1);
- }
- sem_unlock.sem_num = member;
- /*Attempt to lock the semaphore set*/
- if((semop(sid, &sem_unlock, 1))==-1)
- {
- fprintf(stderr, "Unlock failed/n");
- exit
- }
- else
- printf("Semaphore resources incremented by one(unlocked)/n");
- dispval(sid, member);
- }
- void removesem(int sid)
- {
- semctl(sid, 0, IPC_RMID,0);
- print("Semaphore removed/n");
- }
- unsigned short get_member_count(int sid)
- {
- union semum semopts;
- struct semid_ds mysemds;
- semopts.buf= &mysemds;
- /*Return number of member in the semaphore set*/
- int rc;
- if((rc=semctl(sid, 0, IPC_STAT, semopts))==-1)
- {
- perror("semctl");
- return(-1)
- }
- return(semopts.buf->sem_nsems);
- }
- int getval(int sid, int member)
- {
- int semval;
- semval= semctl(sid, member,GETVAL, 0)
- reval semval;
- }
- void changemode(int sid, char *mode)
- {
- int rc;
- union semun semopts;
- struct semid_ds mysemds;
- /*Get current values for internal data structure */
- semopts.buf=&mysemds;
- rc = semctl(sid, 0, IPC_STAT, semopts);
- if(rc ==-1)
- {
- perror("semctl");
- exit(1);
- }
- printf("Old permission were %o/n", semopts.buf->perm.mode);
- /* Change the permission on the semaphore */
- sscanf(mode,"%ho",&semopts.buf->sem_perm.mode);
- /*Update the internal data structure */
- semctl(sid,0, IPC_SET, semopts);
- printf("Updated....../n");
- }
- void dispval(int sid, int member)
- {
- int semval;
- semval= semctl(sid, member, GETVAL,0);
- printf("semval for member %d is %d/n", member ,semval);
- }
- void usage(void)
- {
- fprintf(stderr, "semtool -Autility for thinking with semaphores/n");
- fprintf(stderr, "/nUSAGE: semtool (c)reate <semcount>/n");
- fprintf(stderr, " (l)ock <sem #>/n");
- fprintf(stderr, " (u)nlock <sem #>/n");
- fprintf(stderr, " (d)elete/n");
- fprintf(stderr, " (m)ode <mode>/n");
- exit(1);
- }
边栏推荐
- Nodemcu-esp8266 development (vscode+platformio+arduino framework): Part 5 --blinker_ MIOT_ MULTI_ Outside (lighting technology app + Xiaoai classmate control socket multiple jacks)
- PolyWorks script development learning notes (4) - data import and alignment using file import
- LeetCode每日一题(2212. Maximum Points in an Archery Competition)
- Numerical analysis notes (I): equation root
- Hudi 快速体验使用(含操作详细步骤及截图)
- The number of weak characters in the game (1996)
- Hudi 数据管理和存储概述
- 【Kotlin疑惑】在Kotlin类中重载一个算术运算符,并把该运算符声明为扩展函数会发生什么?
- Win10安装ELK
- Please tell me how to set vscode
猜你喜欢
Hudi 快速体验使用(含操作详细步骤及截图)
PolyWorks script development learning notes (4) - data import and alignment using file import
CATIA automation object architecture - detailed explanation of application objects (III) systemservice
Solve editor MD uploads pictures and cannot get the picture address
图像修复方法研究综述----论文笔记
[kotlin learning] classes, objects and interfaces - define class inheritance structure
Learning C language from scratch -- installation and configuration of 01 MinGW
Spark cluster installation and deployment
There is no open in default browser option in the right click of the vscade editor
LeetCode每日一题(2212. Maximum Points in an Archery Competition)
随机推荐
CATIA automation object architecture - detailed explanation of application objects (I) document/settingcontrollers
全球KYC服务商ADVANCE.AI 活体检测产品通过ISO国际安全认证 产品能力再上一新台阶
Run flash demo on ECS
Patent inquiry website
Nodemcu-esp8266 development (vscode+platformio+arduino framework): Part 3 --blinker_ MIOT_ Light (lighting technology app control + Xiaoai classmate control)
Detailed steps of windows installation redis
Flink学习笔记(十)Flink容错机制
Derivation of Fourier transform
Crawler career from scratch (II): crawl the photos of my little sister ② (the website has been disabled)
What do software test engineers do? Pass the technology to test whether there are loopholes in the software program
解决Editor.md上传图片获取不到图片地址问题
307. Range Sum Query - Mutable
Flink learning notes (10) Flink fault tolerance mechanism
Crawler career from scratch (V): detailed explanation of re regular expression
The rise and fall of mobile phones in my perspective these 10 years
Install database -linux-5.7
Numerical analysis notes (I): equation root
Find all possible recipes from given supplies
Utilisation de hudi dans idea
制作jetson nano最基本的根文件系统、服务器挂载NFS文件系统