select函数监听管道的问题

bupo_007 2010-11-29 12:31:04
我写了一个程序,有三个进程,一个主进程和两个子进程,process、process1、process2
主进程和两个子进程通过四个管道进行通信,主进程调用select函数监听管道的读端来处理process1和process2的数据,并在管道的写端给process1和process2发送数据,代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/wait.h>
#include <sys/stat.h>

#define Max 10
int main(){

int sv;
//主进程向子进程写数据的管道
int fdw1[2],fdw2[2];
//主进程从子进程读数据的管道
int fdr1[2],fdr2[2];

//创建四个管道,形成两个全双工管道
pipe(fdr1);
pipe(fdr2);
pipe(fdw1);
pipe(fdw2);
char buf[512];
//监听文件描述符集
fd_set rfd;
struct timeval timeout;

FD_ZERO(&rfd);

if(fork()==0){//process1
//sleep(3600);
printf("process1 running!\n");
close(fdr1[0]);//write data to fdr1[1]
close(fdw1[1]);//read data from fdw1[0]
int t;
while(1){
t = rand() % 5;//随机睡一会儿
sleep(t);
write(fdr1[1],"process1\0",9);
read(fdw1[0],buf,512);
if(strcmp(buf,"kill")==0)
exit(1);
printf("process1 read %s\n",buf);
}

}
if(fork()==0){//process2
printf("process2 running!\n");
close(fdr2[0]);//write data to fdr2[1]
close(fdw2[1]);//read data from fdw2[0]
int t;
while(1){
t = rand() % 5;//随机睡一会儿
sleep(t);
write(fdr2[1],"process2\0",9);
read(fdw2[0],buf,512);
if(strcmp(buf,"kill")==0)
exit(1);
printf("process2 read %s\n",buf);
}
}
printf("主进程running\n");
close(fdr1[1]);//该管道仅用于读fdr1[0]
close(fdr2[1]);//该管道仅用于读fdr2[0]
close(fdw1[0]);//该管道仅用于写fdw1[1]
close(fdw2[0]);//该管道仅用于写fdw2[0]
FD_SET(fdr1[0],&rfd);
FD_SET(fdr2[0],&rfd);

int max=fdr1[0]>fdr2[0]?fdr1[0]:fdr2[0];
printf("max is :%d\n",max);
printf("fdr1[0] is: %d;fdr2[0] is :%d\n",fdr1[0],fdr2[0]);
int i=0;
int timerand;
while(i<Max){
int se=select(max+1,&rfd,NULL,NULL,NULL);
printf("se is %d\n",se);

if(se>0){
if(FD_ISSET(fdr1[0],&rfd)){
read(fdr1[0],buf,512);
printf("from process1:%s\n",buf);
if(i==Max-1)
write(fdw1[1],"kill\0",5);
else
write(fdw1[1],"hello process1\0",15);
timerand=rand()%3;
sleep(timerand);
}
if(FD_ISSET(fdr2[0],&rfd)){
read(fdr2[0],buf,512);
printf("from process2:%s\n",buf);
if(i==Max-1)
write(fdw1[1],"kill\0",5);
else
write(fdw2[1],"hello process2\0",15);
timerand=rand()%3;
sleep(timerand);
}
}
i++;
}
wait(&sv);
wait(&sv);
return 1;
}

遇到的问题是:process2在read管道时阻塞,即主进程select函数没有监听到process2发送的数据,所以没给process2发送数据,process2就一直阻塞在read管道。
请指教,在线等,谢谢!
...全文
551 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
hyrz183 2011-01-14
  • 打赏
  • 举报
回复
把管道描述符设置成非阻塞的
justkk 2011-01-11
  • 打赏
  • 举报
回复
主进程调用select时,只有一个管道可读的话,只会给那个管道对应的子进程发送kill
可以修改为在循环之后,给两个管道同时写入"kill"
justkk 2011-01-11
  • 打赏
  • 举报
回复
select返回后,会修改集合本身,所以需要把这3句话放入循环之内。
FD_ZERO(&rfd);
FD_SET(fdr1[0], &rfd);
FD_SET(fdr2[0], &rfd);

另外,lz的退出逻辑有问题,只能给一个子进程发送"kill",自己改改吧
sbdt123 2010-11-29
  • 打赏
  • 举报
回复
帮楼主顶一下,小弟能力太矮
bupo_007 2010-11-29
  • 打赏
  • 举报
回复
等啊等,这个问题纠结很久了啊,大侠们~~
bupo_007 2010-11-29
  • 打赏
  • 举报
回复
等解答~~
bupo_007 2010-11-29
  • 打赏
  • 举报
回复
高手们,赐教啊~~~~~~~~~·
bupo_007 2010-11-29
  • 打赏
  • 举报
回复
谢了
[Quote=引用 3 楼 sbdt123 的回复:]

帮楼主顶一下,小弟能力太矮
[/Quote]

70,037

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧