Linux ipc------System V信号量
来源:互联网 发布:知乎 代购 吐槽 编辑:程序博客网 时间:2024/05/22 08:06
信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)所拥有。(1)信号量的值为正的时候,说明它空闲。所测试的线程可以锁定而使用它。(2)若为0,说明它被占用,测试的线程要进入睡眠队列中,等待被唤醒。
二.信号量的分类
在学习信号量之前,我们必须先知道——Linux提供两种信号量:
(1)内核信号量,由内核控制路径使用(驱动开发中使用)
(2)用户态进程使用的信号量,这种信号量又分为POSIX信号量和SYSTEM V信号量。
POSIX信号量又分为有名信号量和无名信号量。
(1)有名信号量,其值保存在文件中, 所以它可以用于线程也可以用于进程间的同步。(2)无名信号量,其值保存在内存中。
三、POSIX 信号量与SYSTEM V信号量的比较
1. 对POSIX来说,信号量是个非负整数。常用于线程间同步。
而SYSTEM V信号量则是一个或多个信号量的集合,它对应的是一个信号量结构体,这个结构体是为SYSTEM V IPC服务的,信号量只不过是它的一部分。常用于进程间同步。
2.POSIX信号量的引用头文件是“<semaphore.h>”,而SYSTEM V信号量的引用头文件是“<sys/sem.h>”,它通常依赖于另两个头文件:
- #include <sys/types.h>
- #include <sys/ipc.h>
3.从使用的角度,System V信号量是复杂的,而Posix信号量是简单。比如,POSIX信号量的创建和初始化或PV操作就很非常方便。
四、System V 信号量函数定义如下:
1、创建信号量集合come from /usr/include/sys/sem.h
函数原型:int semget(key_t key,int nsems,int semflg);
参数解释:
key:所创建或打开信号量集的键值。需要是唯一的非零整数。
nsems:创建的信号量集中的信号量的个数,该参数只在创建信号量集时有效。几乎总是取值为1.
flag:调用函数的操作类型,也可用于设置信号量集的访问权限,两者通过or表示
2、控制信号量集合、信号量come from /usr/include/sys/sem.h
函数原型:int semctl(int semid,int semnum,int cmd,union semun)
参数解释:
sem_id是由semget返回的信号量标识符。
sem_num:表示集合中信号量的编号。
cmd:表示对信号量的操作。(1)对信号量集的操作(2)对单个信号量的操作
semun联合结构的定义:
- semun是在linux/sem.h中定义的:
- /*arg for semctl systemcalls.*/
- 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、信号量操作come from /usr/include/sys/sem.h
函数原型:int semop( int semid, struct sembuf semoparray[], size_t nops )
参数解释:
参数semid:是一个通过semget函数返回的一个信号量标识符
参数nops:标明了参数semoparray所指向数组中的元素个数
参数semoparray:是一个struct sembuf结构类型的数组指针,结构sembuf:来说明所要执行的操作,其定义如下:
- struct sembuf{
- unsigned short sem_num;
- short sem_op;
- short sem_flg;
- }
sem_num是操作的信号量编号
sem_op是信号量的操作,值是一个整数,通常只会用到两个值:1----P操作,-1---V操作。
sem_flg说明函数semop的行为。通常被设置为SEM_UNDO。
五、实例程序
#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>static int semaphore_p(void);static int semaphore_v(void);static int set_semvalue(void);static int get_semvalue(void);union semun { int val; /* value for SETVAL */ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ unsigned short int *array; /* array for GETALL, SETALL */ struct seminfo *__buf; /* buffer for IPC_INFO */};int sem_id;int main(int argc,char *argv){pid_t pid;int i;int value; key_t key;int status;if((pid=fork())==-1){perror("fork");exit(EXIT_FAILURE);}else if(pid==0){if((sem_id=semget((key_t)123456,1,IPC_CREAT|0770))==-1){perror("semget");exit(EXIT_FAILURE);}if (!set_semvalue()) {fprintf(stderr, "Failed to initialize semaphore\n");exit(EXIT_FAILURE);}value=get_semvalue();printf("this is child,the current value is %d\n",value);if(!semaphore_v()){fprintf(stderr, "Failed to v operator\n");exit(EXIT_FAILURE);}value=get_semvalue();printf("the child %d V operator,value=%d\n",i,value);printf("child exit success\n");exit(EXIT_SUCCESS);}else//parent{sleep(3);if((sem_id=semget((key_t)123456,1,IPC_CREAT|0770))==-1){perror("semget");exit(EXIT_FAILURE);}value=get_semvalue();printf("this is parent ,the current value is %d\n",value);printf("the parent will remove the sem\n");if(semctl(sem_id,0, IPC_RMID,(struct msquid_ds*)0)==-1){perror("semctl");exit(EXIT_FAILURE);}return 0;}}static int set_semvalue(void){ union semun sem_union;int value; sem_union.val = 5; if (semctl(sem_id, 0, SETVAL, sem_union) == -1) return(0); printf("set value success,");printf("init value is %d\n",get_semvalue());return(1);}static int get_semvalue(void){int res;if((res=semctl(sem_id, 0, GETVAL)) == -1) { perror("semctl");exit(EXIT_FAILURE); }return res;} static int semaphore_v(void){ struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = 1; /* V() */ //sem_b.sem_flg = SEM_UNDO; sem_b.sem_flg=0;if (semop(sem_id, &sem_b, 1) == -1) { perror("semop");return(0); } return(1);}
- Linux ipc------System V信号量
- Linux IPC实践 --System V信号量(1)
- Linux IPC实践--System V信号量(2)
- 信号量/灯(system V IPC)
- [linux系统编程]System V IPC 信号量做进程间互斥
- linux进程间通讯-System V IPC 信号量
- Linux IPC实践(11) --System V信号量(1)
- Linux IPC实践(12) --System V信号量(2)
- linux IPC 通信 study 三:system v 信号量semphore
- Linux IPC实践(11) --System V信号量(1)
- Linux IPC实践(12) --System V信号量(2)
- Linux System V 信号量
- IPC笔记之System V信号量
- 【记录】system v ipc(3) 信号量
- SYSTEM V IPC——信号量笔记
- Linux C编程--进程间通信(IPC)5--System V IPC 机制2--信号量
- Linux C编程--进程间通信(IPC)5--System V IPC 机制2--信号量
- linux System V IPC总结
- 结构体中指向函数的指针(C) && 结构体中的函数(C++)
- OpenCV中IplImage, CvMat, Mat 基本使用和元素遍历
- C++标准库智能指针(std::auto_ptr)
- 门控时钟的使用
- oracle数据库的导入导出
- Linux ipc------System V信号量
- 电动机的飞车问题
- 黑马程序员-------NSArray(NSMutableArray);
- $(document).ready(function (){})和$(function(){})无区别
- ID3算法
- 树的遍历
- Android开发————CoverFlow3D的实现
- spring原拦截器配置与新命名空间mvc:interceptors配置拦截器对比与注意事项
- 中国版Azure最新上线服务