11

我正在编写一个并发 TCP 服务器,它必须使用“每个连接线程”方法(使用线程池)处理多个连接。我的疑问是哪个是每个线程获取不同文件描述符的最佳方式。

我发现接下来的两种方法是最推荐的:

  1. 所有传入连接并将其描述符存储在数据结构(例如:a )上的主线程。然后每个线程都能够从队列中获取一个 fd。accepts()queue
  2. Accept()直接从每个线程调用。(在Unix 网络编程 V1中推荐)

我发现他们每个人的问题:

  1. 存储所有fd的静态数据结构必须在线程可以读取之前被锁定( )直到他们都达到他们的目标。mutex_lock
  2. 我一直在读到与同时调用相关的Thundering Herdaccept()问题在 Linux 上尚未完全解决,所以也许我需要创建一个人工解决方案,最终使应用程序至少与该方法一样慢1.

资料来源:

(一些链接谈论方法 2:does-the-thundering-herd-problem-exist-on-linux-anymore - 以及我发现的一篇文章(过时):linux-scalability/reports/accept.html

还有一个推荐方法1的SO答案:can-i-call-accept-for-one-socket-from-several-threads-simultaneously


我对这件事真的很感兴趣,所以我会很感激任何关于它的意见:)

4

1 回答 1

6

如您链接的StackOverflow 答案中所述,调用 accept() 的单线程可能是要走的路。您提到了对锁定的担忧,但这些天您会发现 Boost.Lockfree 、 Intel TBB 和其他地方提供了队列实现。如果您愿意,您可以使用其中一个,但您可以只使用条件变量让您的工作线程休眠并在建立新连接时唤醒其中一个。

于 2013-07-13T13:26:25.247 回答