unix XSI IPC-信号量同步例程
发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,原理不多讲,可能查看unix 高级环境编程,只提一些注意点信号量系统限制信号量最大值 32767最多信号量集 128每个集中最多含有250信号量难理解的是标志位SEM_UNDO以下是个人愚见:首先是了
千家信息网最后更新 2025年12月02日unix XSI IPC-信号量同步例程
原理不多讲,可能查看unix 高级环境编程,只提一些注意点
信号量系统限制
- 信号量最大值 32767
- 最多信号量集 128
- 每个集中最多含有250信号量
难理解的是标志位SEM_UNDO
以下是个人愚见:
首先是了解一下"信号量调整值",每一个信号量都会对应有一个调整值,并且对信号量进行操作的时候进行维护。如果设置了SEM_UNDO则立即更新,如果没有何时更新,我也不知道,可能是系统调度吧;
在进行退出,无论是正常还是异常,内核都会遍历一次进程的调整值,进行处理,具体怎样处理有待研究;
个人经验:如果在V 和 P 操作上, 如果需要阻塞的,最好标志位上赋SEM_UNDO,如果不阻塞那就不需要,这样会少点意想不到的错误
网上解释:
每一个独立的信号灯操作可能都需要维护一个调整动作。 Linux 至少为每一个进程
的每一个信号灯数组都维护一个 sem_undo 的数据结构。如果请求的进程没有,就在需 要的时候为它创建一个。这个新的 sem_undo 数据结构同时在进程的 task_struct 数据 结构和信号灯队列的 semid_ds 数据结构的队列中排队。对信号灯队列中的信号灯执行 操作的时候,和这个操作值相抵消的值加到这个进程的 sem_undo 数据结构的调整队列 这个信号灯的条目上。所以,如果操作值为 2 ,那么这个就在这个信号灯的调整条目上 增加 -2 。 当进程被删除,比如退出的时候, Linux 遍历它的 sem_undo 数据结构组,并 实施对于信号灯数组的调整。如果删除信号灯,它的 sem_undo 数据结构仍旧停留在进 程的 task_struct 队列中,但是相应的信号灯数组标识符标记为无效。这种情况下,清除 信号灯的代码只是简单地废弃这个 sem_undo 数据结构。http://3521632.blog.163.com/blog/static/110237933201032041353708/
以下例程
第一:先执行init.c初始化,让信号量集的第1个信号量值为1,当然电脑索引是从0开始的;
第二:再执行多个test.c
intit.c
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/sem.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <string.h>
- int open_semque(void);
- void set_sem(int, int);
- #if 1
- union semun
- {
- int val;
- struct semid_ds buf;
- unsigned short *array;
- };
- #endif
- int main(int argc,char** argv)
- {
- int ret;
- int semque_id;
- semque_id = open_semque();
- set_sem(semque_id, 1);
- ret = semctl(semque_id, 0, GETVAL);
- printf("信号集中第一个信号量的值为:%d\n",ret);
- return 0;
- }
- int open_semque(void)
- {
//创建一个键 - key_t key = ftok("./",100);
- if(key == -1)
- {
- perror("ftok\n");
- exit(1);
- }
- //创建信号量集,
- //IPC_CREAT 存在则打开,不存在则新建,
- //0666是权限
- //设置这个信号量集中包含几个信号量,设为1
- int semque_id = semget(key, 1,IPC_CREAT|0666);
- if(semque_id == -1)
- {
- perror("msgget\n");
- exit(1);
- }
- return semque_id;
- }
- void set_sem(int semque_id, int val)
- {
- //此联合体需要自己去创建,在初始化信号量时需要这个联合体;
- union semun sem_union;
- sem_union.val = val;
- if(semctl(semque_id, 0, SETVAL, sem_union) == -1)
- {
- perror("semctl_set\n");
- exit(1);
- }
- }
test.c
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/sem.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <string.h>
- void v_sem(int);
- void p_sem(int);
- int open_semque(void);
- void set_sem(int, int);
- #if 1
- union semun
- {
- int val;
- struct semid_ds buf;
- unsigned short *array;
- };
- #endif
- int main(int argc,char** argv)
- {
- int ret;
- int semque_id;
- semque_id = open_semque();
- //set_sem(semque_id, 1);
- ret = semctl(semque_id, 0, GETVAL);
- printf("信号集中第一个信号量的值为:%d\n",ret);
- fputs("执行操作V\n",stdout);
- v_sem(semque_id);
- ret = semctl(semque_id, 0, GETVAL);
- printf("信号集中第一个信号量的值为:%d\n",ret);
- int second = 10;
- while(second)
- {
- sleep(1);
- printf("%ds\n",second);
- ret = semctl(semque_id, 0, GETVAL);
- printf("信号集中第一个信号量的值为:%d\n",ret);
- second--;
- }
- fputs("执行操作P\n",stdout);
- p_sem(semque_id);
- ret = semctl(semque_id, 0, GETVAL);
- printf("信号集中第一个信号量的值为:%d\n",ret);
- //semctl(semque_id, 0, IPC_RMID);
- return 0;
- }
- int open_semque(void)
- {
- key_t key = ftok("./",100);
- if(key == -1)
- {
- perror("ftok\n");
- exit(1);
- }
- int semque_id = semget(key, 1,IPC_CREAT|0666);
- if(semque_id == -1)
- {
- perror("msgget\n");
- exit(1);
- }
- return semque_id;
- }
- void set_sem(int semque_id, int val)
- {
- union semun sem_union;
- sem_union.val = val;
- if(semctl(semque_id, 0, SETVAL, sem_union) == -1)
- {
- perror("semctl_set\n");
- exit(1);
- }
- }
- void p_sem(int semque_id)
- {
- struct sembuf arry[1];
- arry[0].sem_num = 0;
- arry[0].sem_op = 1;
- //arry[0].sem_flg = SEM_UNDO;
- int ret;
- //需要通过结构体struct sembuf进行赋值
- if(ret = semop(semque_id, arry, 1))
- {
- perror("semop\n");
- exit(1);
- }
- }
- void v_sem(int semque_id)
- {
- struct sembuf arry[1];
- arry[0].sem_num = 0;
- arry[0].sem_op = -1;
- //arry[0].sem_flg = IPC_NOWAIT;
- arry[0].sem_flg = SEM_UNDO;
- int ret;
- if(ret = semop(semque_id, arry, 1))
- {
- perror("semop\n");
- exit(1);
- }
- }
信号
信号量
信号灯
结构
数据
数据结构
调整
进程
队列
时候
数组
个人
条目
标志
系统
联合体
处理
更新
联合
阻塞
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
部队网络安全形势会议发言
服务器存储维保
阿里云服务器内网有啥用
男生数据库
怎样进去腾讯云服务器
网易MC的服务器
数据库表的最大长度
服务器修改ip限制
网络安全类网络工程
通信网络安全法第七十四条
海南云兆网络技术有限公司联系方式
bim数据库优化
行星边际2服务器地址
北京酷沃网络技术有限公司
附加数据库后怎么查看表的内容
贵州省优汇多互联网科技有限公司
世界各国化学品法规数据库
数据库开启安全审计功能
手机银行的服务器异常
在线服务器在美国法律保护
网络安全管理和工程师
深渊数据库五间竞速
服务器租用如何选择
金山区高科技软件开发使用方法
php数据库搭建实例
城管局网络安全工作总结
长沙致友软件开发公司
聚英教育软件开发
关系型数据库如何优化
扬州大学数据库老师