进程间通信-信号量
来源:互联网 发布:js垂直轮播广告幻灯片 编辑:程序博客网 时间:2024/06/05 02:10
system IPC中,对于每一个新建的信号量 消息队列 共享内存,都有一个在整个系统中唯一的标识符。每个标识也都有唯一对应的关键字,关键字的数据类型为ket_t
在终端输入命令 ipcs ,可以看到目前系统中所有的ipc信息
------------ 共享内存段 --------------键 shmid 拥有者 权限 字节 nattch 状态 0x00000000 1507328 tian 600 2097152 2 目标 0x00000000 884737 tian 600 1048576 2 目标 0x00000000 11141122 tian 600 2097152 2 目标 0x00000000 524291 tian 600 393216 2 目标 0x00000000 10846212 tian 600 524288 2 目标 0x00000000 720901 tian 600 524288 2 目标 0x00000000 1540102 tian 600 393216 2 目标 0x00000000 9830407 tian 600 393216 2 目标 0x00000000 1245192 tian 600 2097152 2 目标 0x00000000 1572873 tian 600 1048576 2 目标 0x00000000 3145738 tian 600 524288 2 目标 0x00000000 9994251 tian 600 12288 2 目标 0x00000000 10944524 tian 600 2097152 2 目标 0x00000000 11239437 tian 600 33554432 2 目标 --------- 信号量数组 -----------键 semid 拥有者 权限 nsems --------- 消息队列 -----------键 msqid 拥有者 权限 已用字节数 消息
ftok()函数用于获得一个IPC关键字,其函数原型为
#include <sys/types.h> #include <sys/ipc.h> key_t ftok(const char *pathname, int proj_id);pathname 必须是一个已经存在并具有访问权限 的文件,pro_jd 只有低8位有效,常用ascii字符代替。当两个都相同时,ftok返回相同的键值。
IPC关键字可以由 ftok()函数获得,也可以设为IPC_PRIVATE ,这时系统会确保创建一个新的IPC,其标识符需要由进程自己记录并告诉其他进程。
信号量函数由semget、semop、semctl三个函数组成。
semget(得到一个信号量集标识符或创建一个信号量集对象)
#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>int semget(key_t key, int nsems, int semflg)nsems 创建信号量集中信号量的个数,该参数只在创建信号量集时有效
msgflg IPC_CREAT:当semflg&IPC_CREAT为真时,如果内核中不存在键值与key相等的信号量集,则新建一个信号量集;如果存在这样的信号量集,返回此信号量集的标识符
IPC_CREAT|IPC_EXCL:如果内核中不存在键值与key相等的信号量集,则新建一个消息队列;如果存在这样的信号量集则报错
semop(完成对信号量的P操作或V操作)
#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>int semop(int semid, struct sembuf *sops, unsigned nsops)
sops:指向进行操作的信号量集结构体数组的首地址,此结构的具体说明如下:
struct sembuf {
unsighed short semnum;
short sem_op;
short sem_flag
};
struct sembuf sem_get={0,-1,IPC_NOWAIT}; /*将信号量对象中序号为0的信号量减1*/
struct sembuf sem_get={0,1,IPC_NOWAIT}; /*将信号量对象中序号为0的信号量加1*/
struct sembuf sem_get={0,0,0}; /*进程被阻塞,直到对应的信号量值为0*/
flag一般为0,若flag包含IPC_NOWAIT,则该操作为非阻塞操作。若flag包含SEM_UNDO,则当进程退出的时候会还原该进程的信号量操作,这个标志在某些情况下是很有用的,比如某进程做了P操作得到资源,但还没来得及做V操作时就异常退出了,此时,其他进程就只能都阻塞在P操作上,于是造成了死锁。若采取SEM_UNDO标志,就可以避免因为进程异常退出而造成的死锁。
#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>int semctl(int semid, int semnum, int cmd, union semun arg)常用的cmd有,SETVAL,用联合体中val成员的值设置信号量集合中单个信号量的值
IPC_RMID 立即删除信号量集
例子:
#include <stdarg.h>#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#include <errno.h>#include <linux/ipc.h>#include <linux/sem.h>#include <linux/shm.h>#if 0union semun{ int val; /*val for SETVAL*/ struct semid_ds *bur; /*buffer for IPC_STAT,IPC_SET*/ unsigned short *array; /*array for getall,setall*/ struct seminfo *_buf; /*buffer for IPC_INFO*/};#endif /*define a function pid_printf*/void pid_printf(char *format, ...){ va_list ap; va_start(ap, format); printf("[%d]%d:", getpid(),__LINE__); vprintf(format, ap);}/*release sem*/void sem_release(int id){ struct sembuf sb; sb.sem_num = 0; sb.sem_op = 1; sb.sem_flg = SEM_UNDO; pid_printf("releaseing..\n"); if(semop(id, &sb, 1) == -1) { pid_printf("semop"); exit(-1); } pid_printf("releassed OK.\n");}/*request sem*/void sem_request(int id){ struct sembuf sb; sb.sem_num = 0; sb.sem_op = -1; sb.sem_flg = SEM_UNDO; pid_printf("requesting..\n"); if(semop(id, &sb, 1) == -1) { pid_printf("semop error!\n"); exit(-1); } printf("request OK!\n");}/*delete sem*/void sem_delete(int id){ printf("master exiting; delete sem\n"); if(semctl(id, 0, IPC_RMID, 0) == -1) { pid_printf("error relesing sem\n"); }}int main(int argc, char *argv[]){ int id; union semun sun; if(argc < 2) { id = semget(IPC_PRIVATE, 1, SHM_R|SHM_W); if(id != -1) { sun.val = 1; if(semctl(id, 0, SETVAL, sun) == -1) { pid_printf("semctl failed\n"); exit(-1); } } } else { id = atoi(argv[1]); pid_printf("using existing sem [%d]\n", id); } if(id == -1) { pid_printf("sem request failed...\n"); return 0; } pid_printf("sucessfully! id=[%d]\n", id); while(1) { int action; printf("1.Release\n"); printf("2.Request\n"); printf("3.Exit-delete\n"); printf("Your choice:"); scanf("%d", &action); switch(action) { case 1: sem_release(id); break; case 2: sem_request(id); break; case 3: sem_delete(id); exit(0); break; } } return 0;}
- 进程间通信 信号量
- 进程间通信--信号量
- 进程间通信-信号量
- 进程间通信-信号量
- 进程间通信--信号量
- 【进程间通信】信号量
- 进程间通信----信号量
- 进程间通信:信号量
- 进程间通信-信号量
- 进程间通信-信号量
- 进程间通信--信号量
- 进程间通信--信号量
- 进程间通信---->信号量
- 进程间通信-信号量
- 进程间通信-信号量
- 进程间通信--信号量
- 进程间通信----信号量
- 进程间通信-信号量
- Parentheses Balance(括号匹配)--栈
- 最大子矩阵和问题
- 003
- IOS7.1下载企业版应用报“xxx证书无效”的解决方案
- Week 1
- 进程间通信-信号量
- codeforces237C Primes on Interval
- Using DLP tools for cloud computing security
- 扑克牌顺子问题
- 12岁的少年教你用Python做小游戏
- 最大m子段和问题
- Game
- MySQl索引创建
- 习近平会见纳米比亚总理根哥布