【问题标题】:Linux Networking IO Noob: Select() and Recvfrom, Blocking or Non-blocking?Linux Networking IO Noob:Select() 和 Recvfrom,阻塞还是非阻塞?
【发布时间】:2013-06-15 02:31:13
【问题描述】:

我继承了一段从 UDP 套接字读取数据的代码。我需要一些帮助来弄清楚这里发生了什么,以及我是否可以提高任何性能。

代码首先调用 select(),然后调用 recvfrom()。根据我的研究,似乎只有在 select() 返回有可用数据的事实时才调用 recvfrom() 。这段代码基本上由一个持续监听多播消息的线程组成。因此,它基本上位于 select() 例程中,直到它接收到数据或超时。

我想知道是否有更好的方法来提高这段代码的性能。首先, select() 是否必要?基于这个线程:setting timeout for recv fcn of a UDP socket 看来我可以设置 recvfrom() 命令本身的超时。这会给我带来什么吗?此外,根据一些研究,我已经看到很多没有 select() 的实现。这是为什么呢?

另外,理想情况下,我想释放尽可能多的 CPU。有没有办法让进程进入睡眠状态,直到它收到一个数据包?话虽如此,为了简单起见,我想一次收到一个完整的数据包。

提前感谢您的帮助。

【问题讨论】:

  • 请出示代码,我们也可以研究一下:)

标签: c++ c sockets udp


【解决方案1】:

recvfrom 阻塞或select 正在等待事件时,进程实际上处于休眠状态;也就是说,它没有计划运行。因此,您现有的代码(至少如果我正确解释了您的描述)已经满足您的第一个要求。

有没有办法让进程进入休眠状态,直到它收到数据包?

UDP 是一种“数据报包服务”。 (引自man 7 udp)。也就是说,它总是发送和接收完整的数据包。因此,使用 UDP,您永远不必担心您的第二个要求:

为了简单起见,我想一次收到一个完整的数据包。

总而言之,我会说你没有问题。

但是,您可以删除 select() 调用,如果它只等待一个描述符,假设您能够 setsocketopt() SO_RCVTIMEO (您可能可以这样做,尽管 Posix 允许个人实现不允许设置选项,所以没有绝对的保证。)我怀疑你是否会注意到这样做的任何性能改进,但它应该节省几微秒。

【讨论】:

    【解决方案2】:

    有没有办法让进程进入休眠状态,直到它收到数据包?

    你已经在这样做了。这就是 select() 的作用,或者是阻塞模式下的 recvfrom()。

    为了简单起见,我想一次收到一个完整的数据包。

    这就是 UDP 已经为您做的事情。

    【讨论】:

      【解决方案3】:

      这可能会有所帮助:10k problem

      【讨论】:

        【解决方案4】:
        I can just set the timeout of the recvfrom() command itself
        

        如果 select 只等待一个文件描述符(例如套接字),那么与您的建议没有太大区别。但如果它管理的不止一个,那么就没有更好的解决方案了。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-11-13
          • 2014-10-19
          • 1970-01-01
          • 2017-09-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-07-06
          相关资源
          最近更新 更多