我想知道:
当apipe
关闭时,将为管道的文件描述符设置什么状态?
我尝试下面的代码,在子进程关闭所有文件描述符后,投票认为所有文件描述符都可以读取!对吗?或者只是我在代码中犯了一些错误?
我使用suse和gcc。
#include <stdio.h>
#include <unistd.h>
#include "../../../myInclude/apue.h"// this is ok
#include <sys/poll.h>
int main(int argc, char **argv)
{
int fd1[2]; int fd2[2]; int fd3[2];
pid_t pid;
if(pipe(fd1)<0 ||pipe(fd2)<0 ||pipe(fd3) <0)
err_sys("pipe error");//this is a error deal function .it will exit the program and print error message.
if((pid = fork()) <0)
err_sys("fork() error");
else if(pid == 0)
{
close(fd1[0]);
close(fd2[0]);
close(fd3[0]);
if(write(fd1[1],"hello fd1 write!",17)!= 17)
err_sys("write 1error ");
sleep(2);
if(write(fd2[1],"hello fd2 write!",17)!=17)
err_sys("write 2error");
sleep(2);
if(write(fd3[1],"hello fd3 write!",17)!= 17)
err_sys("write 3error");
sleep(2);
close(fd1[1]);
close(fd2[1]);
close(fd3[1]);
}
else
{
close(fd1[1]);
close(fd2[1]);
close(fd3[1]);
struct pollfd fd[3];
fd[0].fd = fd1[0];
fd[1].fd = fd2[0];
fd[2].fd = fd3[0];
fd[0].events = POLLIN;
fd[1].events = POLLIN;
fd[2].events = POLLIN;
while(poll(fd,3,3000) >0)
{
printf("now I come \n");
int i = 0,n;
char line[MAXLINE];
for(; i< 3; i++)
{
if(fd[i].revents = POLLIN)
if ((n =read(fd[i].fd,line,MAXLINE))< 0)
err_sys("read error : %d",i);
else
{
line[n] = 0;
printf("read from pipe %d : %s\n",i,line);
}
}
}
close(fd1[0]);
close(fd2[0]);
close(fd3[0]);
}
return 0;
}
我认为在子进程关闭所有写文件描述符之后,轮询将设置
poll
pollhup,但它只是设置pollin!我在看书。我知道这是一本旧书。所以我想知道民意测验现在是怎么进行的?是否设置了关闭管道的pollin?或者仅仅因为Linux?或者我的密码错了?
最佳答案
您应该始终使用-Wall
选项编译程序(至少如此)。这会告诉你这个问题:
if(fd[i].revents = POLLIN)
条件将始终为true,因为这是一个赋值,而不是比较,并且
POLLIN
是非零的。以下也不正确,尽管更好:if(fd[i].revents == POLLIN)
如果
POLLIN
是revents
中设置的唯一标志,则为真。也许这就是你想检查的,但通常的测试是:if(fd[i].revents & POLLIN)
它将检查是否设置了
POLLIN
位,表明read
不会阻塞。在读取失败后可以检测到错误情况,因此不必检查是否设置了例如
POLLHUP
。在输入套接字上测试POLLHUP
不是一个好主意,因为即使可以读取数据,也可以设置标志,而且通常需要读取数据。关于c - 轮询如何处理封闭的管道,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18300077/