民意调查如何处理封闭式管道

时间:2013-08-18 14:23:14

标签: c linux pipe

我想知道:

关闭pipe时,管道文件描述符的状态poll是什么?

我尝试下面的代码,在子进程关闭所有文件描述符后,轮询只是认为所有文件描述符都可以读取!是对的吗?或者我在这段代码中犯了一些错误?

我使用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;
}

我认为在子进程关闭所有写文件描述符之后,轮询将设置revents POLLHUP 。但它只是将其设置为 POLLIN

我正在读这本书。我知道这是一本旧书。所以我想知道民意调查现在如何运作?是否将 POLLIN 设置为关闭管道?还是仅仅因为Linux?或者我的代码错了?

2 个答案:

答案 0 :(得分:4)

您应该始终使用-Wall选项(至少)编译您的程序。那会告诉你这个问题:

if(fd[i].revents = POLLIN)

条件将始终为真,因为这是一个赋值,而不是比较,POLLIN不为零。以下情况也不正确,尽管它更好:

if(fd[i].revents == POLLIN)

如果POLLINrevents中设置的唯一标志,那将是真的。也许这就是你认为你想要检查的,但正常的测试将是:

if(fd[i].revents & POLLIN)

将检查POLLIN位是否已设置,表示read不会阻止。

在读取失败后可以检测到错误情况,因此没有必要检查是否设置了POLLHUP。在输入套接字上测试POLLHUP并不是一个好主意,因为即使数据可供读取,也可以设置标志,并且通常需要读取数据。

答案 1 :(得分:2)

当管道的书写结束时,阅读端对select()poll()显示为“可读” - 这是因为read()不会阻止。

当您致电read()时,返回值将为零,表示文件结束。