Linux下的信号量
来源:互联网 发布:上古卷轴5 初始python 编辑:程序博客网 时间:2024/05/16 18:58
linux下的信号量本身就是临界资源,所以PV操作都是原子操作。
下面是实现二元信号量的代码,二元信号量就是互斥锁。
信号量代码中的semop函数是进行PV操作的核心函数,semop的函数原型为:
int semop (int semid, struct sembuf* sops, unsigned nsops);
第一个参数semid为获得的信号量集标识符,第二个参数是一个指向定义的结构体的指针,第三个参数是信号量的个数。
semid由semget获得;
定义的结构体为:
struct sembuf
{
unsigned short sem_num; /* semaphore number */ sem_num是将信号量集视为一个数组的数组下标,第一个信 号量下标为0
short sem_op; /* semaphore operation */ op决定是P操作还是V操作,P操作为-1(信号量-1),V操 作为1(信号量+1)
short sem_flg; /* operation flags */ flags有多个选项
};
flags:
IPC_NOWAIT //对信号的操作不能满足时,semop()不会阻塞,并立即返回,同时设定错误信息。
SEM_UNDO //程序结束时(不论正常或不正常),保证信号值会被重设为semop()调用前的值。这样做的目的在于避免程序在异常情况下结束时未将锁定的资源解锁,造成该资源永远锁定。
如果父进程在进行了P操作后异常退出,SEM_UNDO可以保证子进程不用一直等待父进程的V操作,避免死锁。
0 // 缺省在二元信号量中我们一般将flags设为SEM_UNDO,防止出现死锁问题。
comm.h
1 #ifndef _COMM_H_ 2 #define _COMM_H_ 3 4 #include<stdio.h> 5 #include<sys/types.h> 6 #include<sys/ipc.h> 7 #include<sys/sem.h> 8 #include<stdlib.h> 9 10 #define PATHNAME "." 11 #define PROJ_ID 0x6666 12 13 int creat(int nums); 14 int get(int nums); 15 int destory(int semid); 16 int init(int semid,int nums,int initval); 17 int P(int semid,int which); 18 int V(int semid,int which); 19 union semun{ 20 int val; 21 struct semid_ds *buf; 22 unsigned short *arrary; 23 struct semiofo *_buf; 24 }; 25 26 #endif
comm.c
1 #include"comm.h" 2 3 4 static int com(int nums,int flags) 5 { 6 key_t key=ftok(PATHNAME,PROJ_ID); 7 if(key<0) 8 { 9 perror("ftok"); 10 return -1; 11 } 12 int semid=semget(key,nums,flags); 13 if(semid<0) 14 { 15 perror("semid"); 16 return -2; 17 } 18 return semid; 19 } 20 21 int creat(int nums) 22 { 23 return com( nums,IPC_CREAT|IPC_EXCL|0666); 24 } 25 26 int get(int nums) 27 { 28 return com(nums,IPC_CREAT); 29 } 30 31 int destory(int semid) 32 { 33 if(semctl(semid,0,IPC_RMID)<0) 34 { 35 perror("semctl"); 36 return -1; 37 } 38 return 0; 39 } 40 41 int init(int semid,int nums,int initval) 42 { 43 union semun un; 44 un.val=initval; 45 if(semctl(semid,nums,SETVAL,un)<0) 46 { 47 perror("semctl"); 48 return -1; 49 } 50 return 0; 51 } 52 53 static int sempv(int semid,int which,int op) 54 { 55 struct sembuf _sf; 56 _sf.sem_num=which; 57 _sf.sem_op=op; 57 _sf.sem_op=op; 58 _sf.sem_flg=SEM_UNDO; 59 if(semop(semid,&_sf,1)<0) 60 { 61 perror("semop"); 62 return -1; 63 } 64 return 0; 65 } 66 67 int P(int semid,int which) 68 { 69 return sempv(semid,which,-1); 70 } 71 int V(int semid,int which) 72 { 73 return sempv(semid,which,1); 74 }
1 #include"comm.h" 2 3 int main() 4 { 5 int semid=creat(1); 6 init(semid,0,1); 7 pid_t id=fork(); 8 if(id==0) 9 {//child 10 int _semid=get(0); 11 while(1) 12 { 13 P(_semid,0); 14 printf("A"); 15 fflush(stdout); 16 usleep(300000); 17 printf("A"); 18 fflush(stdout); 19 usleep(623456); 20 V(_semid,0); 21 } 22 } else 23 {//father //我们选择让AB成对出现,保证每个进程都有PV操作 24 while(1) 25 { 26 P(semid,0); 27 usleep(100000); 28 printf("B"); 29 fflush(stdout); 30 usleep(400000); 31 printf("B"); 32 fflush(stdout); 33 usleep(200000); 34 V(semid,0); 35 } 36 pid_t ret=waitpid(id,NULL,0); 37 if(ret<0) 38 { 39 printf("wait success!\n"); 40 } 41 } 42 return 0; 43 }
- Linux 下的信号量
- linux下的信号量
- linux下的信号量
- Linux下的信号量
- linux下的信号量(semaphore)
- linux下信号量的使用
- linux下进程的信号量
- 浅析Linux下的信号量
- Linux系统下信号量的用法
- linux下kill的信号量列表
- Linux下的线程、信号量使用简记
- linux下的信号量操作示例
- linux下信号量semaphore的应用
- linux下信号量semaphore的应用
- linux下信号量和互斥锁的区别
- Unix/Linux下的IPC---信号量集
- 如何理解linux下的互斥量 信号量
- Linux下信号量的使用与处理
- c++第六次实验
- unity批量更改assetbundle名称、清除名称打包脚本
- Mongodb学习(6)pymongdb的数据库的拷贝
- webpack import css文件的环境配置遇到的Module build failed: Unknown word 及其他
- LeetCode 162. Find Peak Element
- Linux下的信号量
- [DP] BZOJ 4897 [Thu Summer Camp2016]成绩单
- [usaco]Greedy Gift Givers题解
- spring cloud之简单介绍
- 【锁机制】悲观锁和乐观锁
- Python第三方库——OpenCV
- HTTP协议解析(粗略版)
- PHP闭包(Closure)初探_豆浆油条
- 常用http状态码