【问题标题】:Optimal number of socket send(..) threads套接字发送(..)线程的最佳数量
【发布时间】:2018-05-13 09:04:56
【问题描述】:

如果我有 N 个套接字数组,并且我需要以尽可能高的速度向每个套接字发送(..)数据,那么执行此操作的最佳线程数是多少?操作系统是linux。

例如如果我有 C 物理内核,是否应该是每个执行发送(..)的 C 线程?会有效率吗?换句话说,我的问题是 linux 内核如何处理 send(..) 系统调用以及提供给它的数据将如何在内核中调度。我记得从 BSD 套接字文档中读到,实际上所有套接字的 send(..) 系统调用都将数据放入由一个线程处理的队列中,因此代码:

thread1 -> send(sock1, ..)
..
threadN -> send(sockN, ..)

将或多或少等同于代码的网络性能(减去在发送到内核之前通过发送处理数据的时间)

thread -> send(sock1, ..), ..., send(sockN, ..)

但那是 1990 年中期的书,我认为现代操作系统应该在那之后改变。

【问题讨论】:

  • 我的个人经验,尽量让系统尽可能高效。试着让它比需要的效率稍微高一点。这种策略具有最佳的结果与努力比。为什么您需要系统超级高效?
  • 我正在审查在特定(罕见)时间段需要向大量套接字发送大量消息的软件代码。例如。每小时一次,它尽可能快地向 100 个套接字发送 100 条不同的消息(每个套接字发送 1 条消息)。目前他们有 100 个线程的解决方案,我认为这不是有效的(他们有 10/20 个物理/虚拟内核)。与开发人员争论,试图了解正确的方法。
  • 好吧,我已经在 1 个单线程中为 150 台设备完成了这项工作。每个得到一个大小为 128 字节的消息有效负载。因此,在这种情况下,多线程效率不高。将整个事情放在一个 for 循环中就足够了。此外,在 1 轮完整的发送消息结束时,我让循环休眠了 10 微秒。这将 CPU 使用率从 82% 降低到 12%。
  • 如果您向 100 个线程发送 100 条消息,则无需回答任何问题。您需要与套接字一样多的线程,并且摆弄它只会使其变慢。任何特定套接字的send() 已经在内核中进行了序列化,并且网络本质上已经将出站数据序列化到所有目的地。让操作系统完成它的工作。不要试图帮助它。

标签: c++ linux multithreading sockets


【解决方案1】:

如果你所有的线程都应该做完全相同的事情,我会说最好的办法是在带有迭代器的单个线程中做这件事。

你可以做的是定义一个链表来保存节点,这些节点将保存每个套接字的文件描述符。在每个小时结束时遍历列表并发送包。 你可以在类里面定义数据发送函数,这样你的工作就可以在main函数中减少了。

我相信这比维护 100 个处于休眠状态的线程要好。

还要确保使用睡眠功能而不是任何类型的毫秒检查。这肯定会降低代码的 CPU 使用率,同时保持性能不变。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-05
    • 2021-09-04
    • 2016-02-22
    • 2016-09-29
    • 1970-01-01
    相关资源
    最近更新 更多