【问题标题】:Wait until file descriptor is not readable anymore without busy loop等到文件描述符在没有繁忙循环的情况下不再可读
【发布时间】:2017-08-01 00:08:54
【问题描述】:

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

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;
}

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

【问题讨论】:

  • 不读它怎么会变得不可读?
  • @Max,FD 与其他进程共享。
  • 在这种情况下,您可能希望其他进程使用 IPC 告诉您“我刚刚清空了这个 fd”。
  • 据我所知,没有什么好的方法可以等待 FD 不再可读,而且还不清楚您希望从中获得什么好处。当然,您可以尝试使用来自给定 FD 的可用数据,直到没有更多可用数据为止。如果您依赖另一个线程或进程来使用数据,那么您可以考虑实现一个显式信号,可能通过管道或信号量。
  • 您提到的所有系统接口都在等待 FD 以一种或另一种方式准备就绪。您正在寻找相反的结果:等待 FD 变得准备好。这些特定的接口没有提供这些。我不知道有什么,但我还没有准备好否认有。

标签: c linux select io epoll


【解决方案1】:

不,当文件描述符没有要读取时,没有直接的方法可以执行诸如向selectpoll 发送“isEmpty”信号或标志之类的事情。

毕竟,任何 fd 和 select 机制的用例是传输数据,而不是不传输数据...所以你可以争论这不是这个系统例程的工作。

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

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

【讨论】:

    【解决方案2】:

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

    另外,不确定是否使用常规 Linux,但对于 OpenWrt,我使用他们的 ustream 库,它允许您通过管道流式传输数据,这将使您的工作更轻松。

    【讨论】:

      猜你喜欢
      • 2016-11-10
      • 2014-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-17
      • 2016-04-13
      • 1970-01-01
      相关资源
      最近更新 更多