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



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

有人能给我一个POLLOUT的真实用法示例吗?

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

  • 当准备好CCD_ 7时,
    • 始终设置POLLIN,因为您总是对读取套接字的另一端发送给您的内容感兴趣。
      • 除非您有大量的传入数据积压,并且您有意让另一端在发送更多数据之前等待
    • 仅当您有未处理的数据要发送到另一端时,才设置POLLOUT
  • 在从poll()返回时如果指示数据可用于读取,
    • 阅读它并用它做点什么
  • 如果从poll()返回指示套接字是可写的,
    • 尝试发送未处理的数据。
      • 如果您成功地写入了所有内容,那么下次就不会通过循环设置POLLOUT
      • 如果你只寄了一部分(或者没有寄),那么把剩下的留着以后用。您将在下一次循环中设置POLLOUT
  • 当您有新数据要发送时(响应读取的数据或响应某个外部事件),您有两种选择:
    • 急切地想马上送一些。您可能不会成功发送任何数据、部分数据或全部数据。就像上一种情况一样,保留下一次未写入的数据部分,并计划在下一次循环中设置POLLOUT,前提是还剩下一些数据
    • 只需保留数据,并计划在下一次循环中设置POLLOUT。(这种选择通常更容易编程,因为您只需要在循环中的一个位置处理写入数据,但另一方面,它会将写入数据延迟到下一次循环。)

从nginx源代码中,我发现:

如果有一些数据要发送,nginx会尝试使用syscall(可能是writev)发送。但是,如果nginx不能一次发送全部数据,它会在pollfd上设置POLLOUT,如果使用poll事件,则等待可写事件。当得到一个可写事件时,nginx会发送剩下的数据。

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

时,很容易重现这种情况

在Raspberry PI 3上工作,Debian,使用带有gcc的c++98。

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

  1. 使用套接字功能打开套接字
  2. 使用fcntl将套接字文件描述符设置为非阻塞模式
  3. 调用connect并检查返回代码

在大多数情况下,connect返回-1。由于存在非阻塞文件描述符,所以很可能会出现这种情况。然后我检查结果代码。

如果是EINPROGRESS,我会在带有POLLOUT的reactor(使用ppoll或epoll)中注册一个事件处理程序。当连接最终完成时,poll将返回并设置POLLOUT。

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

相关内容

  • 没有找到相关文章

最新更新