linux中的进程通信-信号量和有名管道
来源:互联网 发布:php b2c商城系统二次开 编辑:程序博客网 时间:2024/05/16 02:56
linux中的进程通信-信号量和有名管道
1、为了实现一种通用性对信号量函数进行封装(头文件sys/sem.h)
(1)创建一个或者打开一个信号量集
void sem_get(int key,int val[],int len)//信号集中信号个数由len确定{ semid=semget((key_t)key,len,0666); if(semid==-1) { semid=semget((key_t)key,len,0666|IPC_CREAT);//确保获取到信号量集 assert(semid!=-1); union senun v; int i=0; for(;i<len;++i) { v.val=val[len]; semctl(semid,i,SETVAL,v); } }}
(2)p、v操作
void sem_p(int semnum) //资源的使用信号(-1)传参为第几个信号量 (从0开始){ struct sembuf op; op.sem_num=semnum; op.sem_op=-1; op.sem_flg=SEM_UNDO; semop(semid,&op,1);}void sem_v(int semnum)//资源的释放信号(+1){ struct sembuf op; op.sem_num=semnum; op.sem_op=1; op.sem_flg=SEM_UNDO; semop(semid,&op,1);}
4、信号的删除
void sem_del(){ semctl(semid,0,IPC_RMID,NULL);}
2、对于两个进程之间的通信 用一个例子来实现:A、B两个进程,A进程负责接收用户输入,B进程负责执行和输出;当用户在A进程中输入”ok”时,B进程输出“我准备好了”,当用户在A进程中输入“走你”时,B进程开始打印100以内所有素数;
(1)方法一:只用信号量控制,用两个信号量sem1和sem2分别控制“ok”和“走你”;
1>在A进程中:void main(){ int val=2; sem_get((key_t)1234,&val,2); printf("进程A开始:\n"); while(1) { printf("please input:\n"); char buff[128]={0}; fgets(buff,127,stdin); buff[strlen(buff)-1]=0; if(strncmp(buff,"ok",2)==0) { sem_v(0);//信号集中的信息从0下标开始 对第一个信号量进行v操作 } else if(strncmp(buff,"走你",4)==0) { sem_v(1);//对第二个信号量进行v操作 } }}2>在B进程中void main(){ int val=2; sem_get((key_t)1234,&val,2); printf("B进程开始:\n"); while(1) { sem_p(0);//对第一个信号量进行p操作 printf("我准备好了\n"); sem_p(1);//对第二个信号量进行p操作 printf("我开始计算100以内所有素数\n"); int i=1; for(;i<100;++i) { int j=2; for(;j<i;++j) { if(i%j==0)break; } if(i==j || i==1) printf("%d ",i); } printf("\n"); }}
(2)方法二:同时用到了信号量和管道控制:首先设置资源为0,当A进程接收到“ok”时,使用v操作,B进程退出阻塞,输出我准备好了同时进行p操作,当A进程接收到“走你”时,用管道发送“begin”到B进程,B进程开始计算(当然用两个管道阻塞也可以实现)
1>A进程中:void main(){ int val=1; sem_get((key_t)1234,&val,1);//A、B进程控制同一个信号量 printf("A进程开始:\n"); while(1) { printf("please input:\n"); char buff[128]={0}; fgets(buff,128,stdin); buff[strlen(buff)-1]=0; if(strncmp(buff,"ok",2)==0) { sem_v(0); } else if(strncmp(buff,"走你",4)==0) { int fd=open("FIFD",O_WRONLY); assert(fd!=-1); write(fd,"begin",5); } }}2>B进程中void main(){ int val=1; sem_get((key_t)1234,&val,1); printf("B进程开始:\n"); while(1) { sem_p(0);//资源为0 阻塞等待A进程中的v操作的执行 printf("我准备好了\n"); int fd=open("FIFD",O_RDONLY);//管道阻塞 assert(fd!=-1); char buff[128]={0}; read(fd,buff,127); if(strncmp(buff,"begin",5)==0)//判断从管道中读取的数据是否为“begin” { printf("我开始计算100以内素数\n"); //省略计算打印过程 参考方法一 } }}
阅读全文
0 0
- linux中的进程通信-信号量和有名管道
- linux系统中的进程通信(管道和有名管道)
- linux进程通信-有名管道
- linux进程通信--有名管道
- linux 进程间通信之管道和有名管道
- Linux中的通信机制(1) 管道和有名管道
- linux进程通信----FIFO(有名管道)
- linux进程间通信之有名管道
- 进程通信--有名管道
- 进程间通信-管道(有名管道和无名管道)
- linux有名管道通信
- Linux环境进程间通信(一)管道和有名管道
- Linux进程间通信(一)之无名管道(PIPE)和有名管道(FIFO)
- Linux环境进程间通信:管道及有名管道
- Linux进程间通信:管道及有名管道
- Linux环境进程间通信:管道及有名管道
- Linux环境进程间通信: 管道及有名管道
- Linux环境进程间通信:管道及有名管道
- [BZOJ1223][HNOI2002]Kathy函数(数位DP/乱搞)
- 百度地图POI数据爬取,突破百度地图API爬取数目“400条“的限制。
- DNS
- 关于某个数之后的素数
- caffe的MATLAB接口配置
- linux中的进程通信-信号量和有名管道
- 贝叶斯定理与贝叶斯估计
- ES6--变量的解构赋值
- MapReduce的运行
- POJ
- Matlab使用技巧 (如何提取文档数据和表格数据)
- typescript(ng2)中使用nodejs模块的方法
- maven 常用的一些命令
- #228. 噼里啪啦