13

Assuming a pipe,

int pipe_fd[2];
pipe(pipe_fd);

We fork, and expect that one process will write into the pipe at an arbitrary time. In one of the processes, we want to be able to check the contents of the pipe without blocking.

i.e. While a typical read will block if nothing is present and the write end remains open. I want to go do other stuff and potentially even read a bit at a time, do some stuff, and then check back to see if there's more, a 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
}
4

3 回答 3

14

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

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

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

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

于 2012-12-11T00:26:31.017 回答
4

您可以使用该功能检查是否有要读取的数据read()。来自read(3)

When attempting to read from an empty pipe or FIFO:

* If some process has the pipe open for writing and
O_NONBLOCK is set, read() shall return -1 and set
errno to [EAGAIN].

* If some process has the pipe open for writing and
O_NONBLOCK  is  clear,  read() shall block the calling
thread until some data is written or the pipe is
closed by all processes that had the pipe open for
writing.

The read() function shall fail if:

EAGAIN or EWOULDBLOCK

    The file descriptor is for a socket, is marked
    O_NONBLOCK, and no data is waiting to be received.

因此,如果您设置O_NONBLOCK了,您将能够通过简单地调用来判断是否要在管道上读取某些内容read()

提醒一下,来自open(3)

SYNOPSIS
    int open(const char *path, int oflag, ...  );

DESCRIPTION
    Values for oflag are constructed by a
    bitwise-inclusive OR of flags from the following
    list, defined in <fcntl.h>. Applications shall
    specify exactly one  of  the first three values
    (file access modes) below in the value of oflag:

    O_NONBLOCK [...]

我希望它有所帮助。

于 2012-12-11T00:35:27.740 回答
2

R.. 的答案很好,但是 poll 返回在“revents”中设置了标志的文件描述符结构的数量。如果您可以从中读取,fd则该值为 1,但如果设置了任何错误标志,则该值为 1。这意味着 R.. 的回答会说管道在进入错误状态时是可读的。更强大的检查可能是这样的:

bool canReadFromPipe(){
    //file descriptor struct to check if POLLIN bit will be set
    //fd is the file descriptor of the pipe
    struct pollfd fds{ .fd = fd, .events = POLLIN };
    //poll with no wait time
    int res = poll(&fds, 1, 0);

    //if res < 0 then an error occurred with poll
    //POLLERR is set for some other errors
    //POLLNVAL is set if the pipe is closed
    if(res < 0||fds.revents&(POLLERR|POLLNVAL))
    {
        //an error occurred, check errno
    }
    return fds.revents&POLLIN;
}
于 2018-11-19T09:12:00.493 回答