unix XSI IPC-信号量同步例程
发表于:2025-01-25 作者:千家信息网编辑
千家信息网最后更新 2025年01月25日,原理不多讲,可能查看unix 高级环境编程,只提一些注意点信号量系统限制信号量最大值 32767最多信号量集 128每个集中最多含有250信号量难理解的是标志位SEM_UNDO以下是个人愚见:首先是了
千家信息网最后更新 2025年01月25日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安全错误
数据库的锁怎样保障安全
福州app系统软件开发
奉贤区管理软件开发价格表格
我与网络安全共成长征文
ios软件开发怎样选电脑
数据库的存储过程
网络安全人人有责主题班会
彼伏 网络安全
英特尔pc和服务器
数据库是著作权吗
千寻电话软件开发商
南宁服务器带电清洗
方舟服务器吧
硬件嵌入式软件开发
软件开发报价中管理费
服务器连外网安全
数据库管理软件有哪些
女生学计算机网络技术的多吗
c#如何显示数据库中的数据
联想服务器内存怎么拔
中关村网络安全产品
卢龙县网络安全工作会
律师匹配 软件开发
怎么学习neo4j数据库
药业数据库
成都软件开发首选青岗科技
网络安全法包括什么
服务器往移动硬盘拷贝文件速率
服务器跟主机的区别
南关区网络安全服务保障
清软英泰PDM转移服务器