【发布时间】:2011-10-16 21:56:31
【问题描述】:
我正在开发一个程序,我使用 select 从管道中进行选择以进行读取。
问题是我正在使用if(FD_ISSET(pfd[i][0], &read_set)),但验证失败,因为 FD_ISSET 返回 0,但如果我尝试使用 read(pfd[i][0],&c,sizeof(c)) 读取,它将正常工作,并且管道 pfd[0] 中的内容不同像我想要的那样来自 pfd[1]。
我想知道到底发生了什么,因为 FD_ISSET 返回 0 但我实际上可以从中读取内容
编辑
全局变量 CORES 将控制我创建多少进程 下一个代码将创建管道并使用 FD_SET 设置位
for(i=0; i<CORES; i++)
{
if(pipe(pfd[i])==-1)
perror("Ocorreu um erro a criar um pipe");
FD_SET(pfd[i][0], &read_set);
}
read_set 在 main() 启动后立即定义。我在上述代码之后使用 for() 使用 fork() (x = CORES) 创建 x 个进程
那么这部分在父进程中运行:
while (x<CORES){
int selec = select(pfd[CORES-1][0]+1, &read_set, NULL, NULL, NULL);
if(selec>0)
{
if(FD_ISSET(pfd[x][0], &read_set))
{
close(pfd[x][1]);
if(read(pfd[x][0],&c,sizeof(c))==-1)
perror("Ocorreu um erro a ler do pipe");
printf("c= %f \n",c);
c_final+=c;
x++;
}
else
printf("\nFile descriptor pfd[%d][0] is not set\n",x);
}
else if(selec == -1)
perror("Ocorreu um erro no select");
}
问题在于FD_ISSET(pfd[x][0], &read_set) 不会通过,因为它没有设置为 pfd[0] 但它可以设置为 pfd[1] 或反之亦然(因为我不知道它是否会失败0 或 1)
EDIT2:
select() 返回一个 int,表示 read_set 中的文件描述符数。我将 CORES 设置为 2,因此它创建了 2 个进程和 2 个管道,并在 read_set 中设置了 2 个位。我的 select() 正在返回 int 1。它应该返回 int 2 还是 0 计数(所以它会是 0 和 1 = 2)?
【问题讨论】:
-
你在某处做错了什么,显示代码。
-
在调用
select之前,fd_set必须包含你想要等待的所有文件描述符,然后在select返回之后,只有准备好的那些仍然会被设置。我猜你以某种方式搞砸了.. -
您是否使用非阻塞读取来执行此操作?如果没有,则 read 将等待输入,即使您没有在选择时输入,这也会使您看起来像是输入了。
-
while循环在select之外有点奇怪。通常,您会先进行选择,然后使用循环查看设置了哪些描述符。
-
带有
x的while 循环是错误的。或者换一种说法:如果您只对一个fd 感兴趣,为什么还要选择?你可能会忙着等待