带有轮询的非阻塞套接字

341*_*008 11 c sockets posix blocking

几天前,我不得不调查我的应用程序在(显然)处于空闲状态时显示异常高CPU使用率的问题.我将问题跟踪到一个循环,这个循环意味着recvfrom在套接字被设置为O_NONBLOCK-ing 时阻塞一个调用,导致旋转锁定.有两种方法可以解决问题:使用poll或设置套接字阻塞或轮询套接字上的可用数据select.我选择前者因为它更简单.但我想知道为什么任何人会创建一个非阻塞套接字然后单独轮询它.阻塞套接字是否也这样做?使用非阻塞套接字和轮询组合的用例有哪些?在一般情况下它有什么优势吗?

caf*_*caf 8

使用poll()select()使用非阻塞文件描述符有两个优点:

  • 您可以设置阻止超时;
  • 您可以等待任何一文件描述符变得可用.

如果你只有一个文件描述符(套接字)要等待,而你不介意无限期地等待它,那么是; 你可以使用阻止通话.

第二个优势是真正的杀手用例select()和朋友.这意味着您可以处理多个套接字连接,以及标准输入和标准输出以及可能的文件I/O,所有这些都具有单个控制线程.


Sir*_*ers 5

我\xc2\xb4m在这里发帖,因为虽然问题很旧。它以某种方式出现在我的谷歌搜索中,并且肯定没有得到正确的回答。

\n\n

接受的答案只是强调了使用非阻塞套接字的两个优点,但并没有真正深入细节或回答实际问题。

\n\n
    \n
  • 注意:不幸的是,大多数在线“教程”或代码片段仅包含阻塞套接字代码,因此有关非阻塞套接字的知识传播较少。
  • \n
\n\n

至于何时使用其中一种与另一种相比……一般来说,阻塞套接字仅在在线代码片段中使用。在所有(好的)生产应用程序中都使用非阻塞套接字。我\xc2\xb4m不是无知的,如果你知道使用阻塞套接字的实现(并且确保\xc2\xb4s非常有可能与线程结合使用) - 或者让\xc2\xb4s更具体地在a中使用阻塞套接字单线程 - 请告诉我。

\n\n

现在我可以给你一个非常容易理解的例子,还有很多其他的例子。让\xc2\xb4s 以游戏服务器为例。无论玩家是否提供输入(鼠标/键盘)来更改游戏状态,游戏都会按一定的时间间隔进行,游戏状态也会按一定的间隔进行。现在,当套接字在多人游戏中发挥作用时 - 如果您要使用阻塞套接字,除非玩家发送更新,否则游戏状态将不会前进 - 因此,如果他们遇到互联网问题,游戏状态将永远不会一致更新并将更改传播给所有玩家。你将会有一个相当不稳定的经历。

\n\n

现在使用非阻塞套接字,您可以在单线程上运行游戏服务器,更新游戏状态以及套接字,...let\xc2\xb4s 假设 50ms 超时间隔 - 并且套接字数据仅从连接的读取当用户实际发送某些内容时,然后将其输入到服务器模拟中,进行处理并输入到下一个tick的游戏状态计算中。

\n