何时使用轮询C函数的POLLOUT事件?

时间:2012-08-29 02:16:45

标签: c tcp posix polling

我用socket() + POLLIN poll() + recv() + send()编写了一个小型TCP服务器,但我不知道何时发布使用 POLLOUT 轮询或选择writefds来轮询可写事件。

有人能举例说明 POLLOUT 的真实用途吗?

3 个答案:

答案 0 :(得分:18)

通常的模式是使用poll()的非阻塞文件描述符,如下所示:

  • 准备好poll()时,
    • 始终设置POLLIN,因为您始终有兴趣阅读套接字的另一端发送给您的内容。
      • 除非您有大量的传入数据积压,否则您有意在另一端发送更多资料之前等待。
    • 仅当您有未完成的数据发送到另一端时才设置POLLOUT
  • poll()返回后,如果表明数据可供阅读,
    • 阅读并用它做点什么
  • poll()返回时,如果它指示套接字是可写的,
    • 尝试发送您的优秀数据。
      • 如果你设法写下所有内容,那么下次循环时你就不会设置POLLOUT
      • 如果你只是设法发送一些(或者没有),那么请保留其余部分。您将在下一次循环时设置POLLOUT
  • 当您要发送新数据时(响应您阅读的数据或响应某些外部事件),您有两种选择:
    • 急切地尝试立即发送一些。您可以成功发送任何,部分或全部内容。与前一种情况一样,保留下次未写入的数据部分,并计划在下一次循环时设置POLLOUT,只有在剩下一些数据的情况下。
    • 只需保留数据并计划在下次循环时设置POLLOUT。 (这种选择通常更容易编程,因为您只需要处理在循环中的一个位置写入数据,但另一方面它会延迟写入数据直到下一次循环。)

答案 1 :(得分:0)

从nginx来源,我发现:

如果有一些数据需要发送,nginx会尝试使用系统调用(也许是writev)发送它。但是,如果nginx不能一次发送总数据,它将在pollfd上设置POLLOUT,如果使用poll事件,则等待可写事件。获取可写事件时,nginx将发送左侧数据。

当nginx尝试响应大型静态文件

时,很容易重现这种情况

答案 2 :(得分:0)

使用带有gcc的c ++ 98,使用Raspberry PI 3,Debian。 。

在Acceptor / Connector模式和Reactor / Proactor / ACT模式的实现中,我按照以下顺序定期使用POLLOUT:

  1. 使用套接字功能打开套接字。
  2. 使用fcntl将套接字文件描述符设置为非阻塞模式。
  3. 致电连接并检查返回代码。
  4. 在大多数情况下,connect返回-1。由于非阻塞文件描述符,这很可能。然后我检查结果代码。

    如果它是EINPROGRESS,我在反应堆中注册一个事件处理程序(使用ppoll或epoll)和POLLOUT。最终完成连接后,poll将返回POLLOUT设置。

    然后我创建一个新的TcpConnection类并进行通信。