📄 semtool.c
字号:
/*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#if defined(_GNU_LIBRARY_)&&!defined(_SEM_SEMUN_UNDEFINED)#elseunion semun{int val;struct semid_ds *buf;unsigned short int *array;struct seminfo *_buf;};#endifvoid opensem(int *sid,key_t key); /*打开信号量集*/void createsem(int *sid,key_t key,int members); /*创建信号量集*/void locksem(int sid,int member); /*对集合中的某个信号量进行P操作*/void unlocksem(int sid,int member); /*对集合中的某个信号量进行V操作*/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(); /*使用方法提示*/int main(int argc,char *argv[]){key_t key;int semset_id;if (argc==1)usage();/*创建关键字值*/key=ftok(".",'s');/*定义各个参数功能*/switch (tolower(argv[1][0])) {case 'c': /*创建信号量集*/if (argc!=3)usage();createsem(&semset_id,key,atoi(argv[2]));break;case 'l': /*P操作*/if (argc!=3)usage();opensem(&semset_id,key);locksem(semset_id,atoi(argv[2]));break;case 'u': /*V操作*/if (argc!=3)usage();opensem(&semset_id,key);unlocksem(semset_id,atoi(argv[2]));break;case 'd': /*删除信号量集*/if (argc!=2)usage();opensem(&semset_id,key);removesem(semset_id);break;case 'm': /*修改权限*/if (argc!=3)usage();opensem(&semset_id,key);changemode(semset_id,argv[2]);break;default:usage();}return 0;}/*打开信号量集*/void opensem(int *sid,key_t key){/*semget函数创建信号量.第一个参数为关键字值,第二个指出在新信号量集中应创建的信号量的个数 第三个为标志位其值等于 IPC_CREAT|IPC_EXCL|位权位*/if((*sid=semget(key,0,0666))==-1) { printf("semaphore set dose not exist\n");exit (1);}}/*创建信号量集*/void createsem(int *sid,key_t key,int members){int cntr;union semun semopts;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 exists!\n");exit(1);}semopts.val=SEM_RESOURCE_MAX;for(cntr=0;cntr<members;cntr++)semctl(*sid,cntr,SETVAL,semopts);}/*对集合中的某个信号量进行P操作*/void locksem(int sid,int member){struct sembuf sem_lock={0,-1,IPC_NOWAIT}; /*0为要处理的信号量在集合中的索引,-1为信号量操作符 IPC_NOWAIT为操作标志*/printf("get member count %d\n",get_member_count(sid));if(member<0||member>(get_member_count(sid)-1)) {fprintf(stderr,"semaphore member %d out of range\n",member);return;}if(!getval(sid,member)) {fprintf(stderr,"Semaphore resources exhausted (no lock)!\n");exit(1);}sem_lock.sem_num=member;/*semop函数表示信号量操作.第一个参数代表要操作的信号量集,第二个指向要操作的sembuf数组指针 第三个为指向sem_buf结构数组的元素个数*/if((semop(sid,&sem_lock,1))==-1) { fprintf(stderr,"Lock failed\n"); exit(1);}elseprintf("Semaphore resources decremented by one (locked)\n");dispval(sid,member);}/*对集合中的某个信号量进行V操作*/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;}semval=getval(sid,member);if(semval==SEM_RESOURCE_MAX) {fprintf(stderr,"Semaphore not locked!\n");exit(1);}sem_unlock.sem_num=member;if((semop(sid,&sem_unlock,1))==-1) {fprintf(stderr,"Unlock failed\n");exit(1);} elseprintf("Semaphore resources incremented by one (unlocked)\n");dispval(sid,member);}/*删除信号量集*/void removesem(int sid){/*semctl函数表示控制和删除信号量. 第一个参数表示要操作的信号量集,第二个指出集中特定的信号量 第三个表示控制命令*/semctl(sid,0,IPC_RMID,0); /*IPC_RMID表示将信号量从内存中删除*/printf("Semaphore removed\n");}/*活动信号量集中信号量的数目*/unsigned short get_member_count(int sid){union semun semopts;struct semid_ds mysem_ds;semopts.buf=&mysem_ds;semctl(sid,0,IPC_STAT,semopts); /*IPC_STAT表示读取一个信号量集的semid_ds,并存入semun的buf里*/return(semopts.buf->sem_nsems);}/*获得一个信号量当前的值*/int getval(int sid,int member){int semval;semval=semctl(sid,member,GETVAL,0);return semval;}/*改变信号量集的存取权限*/void changemode(int sid,char *mode){int rc;union semun semopts;struct semid_ds mysem_ds;semopts.buf=&mysem_ds;rc=semctl(sid,0,IPC_STAT,semopts);if(rc==-1) {perror("semctl");exit(1);}printf("Old permissions were %o\n",semopts.buf->sem_perm.mode);sscanf(mode,"%ho",&semopts.buf->sem_perm.mode);semctl(sid,0,IPC_SET,semopts); /*表示设置semid_ds中的成员ipc_perm,其值取自semun中的buf*/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(){fprintf(stderr," \n");fprintf(stderr," ********************************* \n");fprintf(stderr," ** 进程同步机制---信号量 ** \n");fprintf(stderr," ********************************* \n");fprintf(stderr," \n");fprintf(stderr," 请输入正确的参数: \n");fprintf(stderr," semtool c <信号量个数> 功能:创建信号量集 \n");fprintf(stderr," l <信号量位置> 功能:对一信号量进行P操作 \n");fprintf(stderr," u <信号量位置> 功能:对一信号量进行P操作 \n"); fprintf(stderr," d 功能:删除信号量集合 \n"); fprintf(stderr," m <权限> 功能:修改信号量集合存取权限 \n");fprintf(stderr," \n");fprintf(stderr," *命令执行成功后可以使用ipcs -s 命令查看信号量集 \n");fprintf(stderr," \n");exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -