等到文件描述符在没有繁忙循环的情况下不再可读

问题描述 投票:0回答:2

等待文件描述符变得可读非常简单:

struct pollfd f;
signed result;

f.fd = a_file_descriptor_a_pipe_in_my_case;
f.events = POLLIN | POLLERR | POLLHUP;

result = poll(&f, 1, timeout_in_millis);
if (result < 0) {
    if (errno == EINTR) {
        // try again
    } else {
        // report error
    }
} else if (result == 0) {
    // timeout
} else {
    fd_is_readable = (f.revents & POLLIN) != 0;
    fd_has_an_error = (f.revents & POLLERR) != 0;
    fd_is_not_valid = (f.revents & POLLNVAL) != 0;
    other_end_of_the_pipe_was_closed = (f.revents & EPOLLHUP) != 0;
}

但是如何在没有繁忙循环的情况下等待文件描述符变为不可读(即为空)?我目前的方法是休眠几毫秒,但这不是我最喜欢的解决方案。

c linux io epoll posix-select
2个回答
0
投票

不,当文件描述符没有

没有
要读取时,没有直接的方法可以执行诸如发送“isEmpty”信号或标志到
select
poll之类的事情。

毕竟,任何 fd 和

select
机制的用例都是传输数据,而不是不传输数据...所以你可能会说这不是这个系统例程的工作。

传输到

select
的唯一事实是文件描述符不再存在,这是“无可用数据”的特殊情况 - 但我认为这不涵盖您的用例。

要么你扭转逻辑并确保数据始终可用,方法是让生产者通过可以检查的描述符发送某种心跳,例如重置计时器,或者你有数据消费者向监控进程发送一个信号(或其他 IPC 消息),向监视器发出“我刚刚清空该 fd”的信号。


0
投票

看看 man read 它说

read
返回
0
这基本上意味着
end of file
这意味着没有更多的数据可以从 fd 读取。 至于不使用循环,您可以尝试基于事件的方法,将回调函数分配给事件,并且当事件发生时将调用该函数。 (链接

另外,对于常规 Linux 不太确定,但对于 OpenWrt,我使用他们的

ustream
库,它允许您通过管道传输数据,这将使您的工作变得更加轻松。

© www.soinside.com 2019 - 2024. All rights reserved.