如何查看管道是否为空

dar*_*pbj 11 c pipe block blocking

假设一个管道,

int pipe_fd[2];
pipe(pipe_fd);
Run Code Online (Sandbox Code Playgroud)

我们fork,并期望一个进程将在任意时间写入管道.在其中一个过程中,我们希望能够在不阻塞的情况下检查管道的内容.

即,如果不存在任何内容并且写入结束保持打开,则典型读取将阻塞.我想去做其他的事情,甚至可能一次读一些,做一些事情,然后检查一下是否还有更多,一个la:

close(pipe_fd[1]);

while(1){
    if(/**Check pipe contents**/){
        int present_chars = 0;    

        while( read(pipe_fd[0],&buffer[present_chars],1) != 0)
            ++present_chars;

        //do something

    }
    else
        //do something else
}
Run Code Online (Sandbox Code Playgroud)

R..*_*R.. 10

你的逻辑是错误的,read当它用完字符时不会返回0; 相反,它会阻止,直到它接收更多的,除非你把非阻塞模式的文件,但随后会返回-1,并设置errnoEWOULDBLOCKEAGAIN而不是返回0,只有时间read永远返回0是当尺寸参数为已达到0或文件结尾.而且,对于管道,文件末尾意味着管道的书写端已经关闭; 文件结束状态不会因为还没有任何可用输入而发生.

话虽如此,最简单的检查方法是:

if (poll(&(struct pollfd){ .fd = fd, .events = POLLIN }, 1, 0)==1) {
    /* data available */
}
Run Code Online (Sandbox Code Playgroud)

但除非您使用非阻塞模式,否则您需要在每次读取操作之前进行此检查.传递更大的缓冲区read而不是一次一个字节地执行它将消除大部分检查成本.