【问题标题】:Reading multiple UDP messages without polling无需轮询即可读取多个 UDP 消息
【发布时间】:2015-11-15 00:19:02
【问题描述】:

我想使用recvmmsg 调用一次从一个单一套接字读取多个UDP 消息。我正在从单个多播组中读取数据。

当我读取 TCP 数据时,我通常使用带有非阻塞套接字(和超时)的poll/select,以便在准备好读取时得到通知。我采用这种方法,因为我知道虚假唤醒问题和阻塞套接字的潜在问题。

由于我的应用程序必须非常快,如果我采用与 recvmmsg 相同的方法,我将引入一个额外的系统调用 (poll/select),这可能会减慢执行速度。

所以我的两个问题如下:

  1. 使用 UDP,我可以使用 recvmmsg 而不使用 poll/select 安全地从 BLOCKING 套接字读取,还是必须应用我用于 TCP 的相同原理(非阻塞 + 轮询)?
  2. 假设我有大量的多播流量,你会选择非阻塞套接字 + recvmmsg only(无投票)并消耗大量 CPU 吗?

我正在使用 Linux:CentOS 7 和 Oracle Linux。

【问题讨论】:

  • 请注意,是否使用 poll/select + 非阻塞套接字取决于您是否需要同时处理多个套接字或读取/写入,而不是使用 TCP 还是 UDP。

标签: c linux sockets multicast recvmmsg


【解决方案1】:

您始终可以使用阻塞模式,同时使用 TCP 和 UDP 套接字。

如果您想强制读取超时,可以使用带有SO_RCVTIMEO 选项的setsockopt()

我遵循这种方法,因为我知道虚假唤醒的问题

什么虚假唤醒?在 25 年的网络编程中从未见过它。

以及阻塞套接字的潜在问题。

也从未听说过。

除非您的平台不支持SO_RCVTIMEO,否则对单个套接字使用select() 和非阻塞模式是没有意义的。首先,这是一个额外的系统调用。

【讨论】:

  • 非常感谢!我忘记了,你是对的!!性能怎么样?我可能是错的,但我在某处读到此设置不可取(不记得我在哪里读过它..我会搜索它)
  • 在 20 多年的网络编程中从未听说过。
  • @EJP - FUD。 “阻塞”听起来很糟糕,所以它一定很糟糕。
  • @MartinJames 是的,两个系统调用一定比一个好:-|
【解决方案2】:

使用阻塞或非阻塞的选项取决于应用程序的最终目的是什么。 - 假设它只是一个显示 UDP 与 TCP 结合使用的示例聊天应用程序,那么您可以使用其中任何一个。 - 但是,如果您打算将此模块作为具有大量数据流动的高度使用的应用程序的一部分,那么创建多个线程/进程来处理不同的任务可能会派上用场。父线程将等待消息,但为了处理它会产生一个不同的子线程,从而使父线程可用于下一条消息。

但简而言之,对于 UDP 应用程序使用不带 poll/select 的阻塞套接字的第一个选项,我认为没有任何问题,因为它只是用于家庭作业。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-12
    相关资源
    最近更新 更多