代码之家  ›  专栏  ›  技术社区  ›  341008 Sylvain

带轮询的非阻塞套接字

  •  11
  • 341008 Sylvain  · 技术社区  · 14 年前

    几天前,我不得不调查一个问题,当我的应用程序(显然)处于空闲状态时,它显示出异常高的CPU使用率。我把这个问题追溯到一个循环,这个循环本来是要阻止 recvfrom 当套接字设置为 O_NONBLOCK -导致旋转锁定。有两种方法可以解决这个问题:将套接字设置为blocking,或者使用 poll select . 我选择前者是因为它更简单。但我想知道为什么有人会创建一个非阻塞套接字,然后分别轮询它。阻塞套接字不也是这样吗?使用非阻塞套接字和轮询组合的用例是什么?一般情况下有什么好处吗?

    4 回复  |  直到 14 年前
        1
  •  10
  •   caf    14 年前

    使用 poll() select()

    • 您可以设置阻止的超时;
    • 你可以等任何一个 设置 使文件描述符变得可用。

    如果您只需要等待一个文件描述符(socket),并且您不介意无限期地等待它,那么是的;你可以用阻塞呼叫。

    选择()

        2
  •  3
  •   Sir Rogers    8 年前

    我在这里发帖,因为虽然这个问题很老了。它出现在我的谷歌搜索不知何故,肯定没有得到正确的回答。

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

    • 注:不幸的是,大多数在线“教程”或代码片段只提供阻塞套接字代码,因此非阻塞套接字的知识传播较少。

    至于什么时候你会用一个来比较另一个。。。通常,阻塞套接字只在联机代码段中使用。在所有(好的)生产应用中,都使用非阻塞套接字。我并不是不知道,如果你知道一个使用阻塞套接字的实现(当然这很可能与线程结合使用),或者让我们更具体地说,在一个线程中使用阻塞套接字-请让我知道。

    现在使用非阻塞套接字,您可以在单个线程上运行gameserver,更新游戏状态以及套接字,使用。。。假设50ms的超时时间间隔-套接字数据只在连接的用户实际发送内容时读取,然后输入服务器模拟、处理并输入游戏状态计算,以供下一次计时。

        3
  •  1
  •   Dummy00001    14 年前

    这种情况通常被称为 紧密循环

    有两种解决问题的方法:使用poll或select将socket设置为blocking或poll,以查找socket上的可用数据。我选择前者是因为它更简单。

    是否确定其他代码部分尚未使用 poll() (或 select()

    否则,是的,切换到阻塞模式是最简单的解决方案。

    向后兼容的解决方案在调用 recvfrom() 使用

    但我想知道为什么有人会创建一个非阻塞套接字,然后分别轮询它。阻塞套接字不也是这样吗?

    对于 我不知道有什么大区别。

    使用非阻塞套接字和轮询组合的用例是什么?一般情况下有什么好处吗?

    可能是一个简单的编码错误。或者有人可能会认为在紧密循环中接收会以某种方式提高性能。

        4
  •  0
  •   Brian Tompsett - 汤莱恩 andrewwong97    9 年前

    nonblocking 因为即使是阻塞的套接字有时也会变成就绪状态(当数据到达但有校验和错误并且被丢弃时)-即使没有数据可读取。那就去吧