从多个线程调用accept()

时间:2013-07-13 12:57:52

标签: linux multithreading concurrency tcp

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

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

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

  3. 我发现每个人都遇到的问题:

    1. 在线程可以读取之前,存储所有fd的静态数据结构必须锁定mutex_lock),因此在相当多的线程想要读取的情况下在完全相同的时刻我不知道在他们所有人都能实现目标之前会花多少时间。
    2. 我一直在读,与accept()调用相关的Thundering Herd问题在Linux上还没有完全解决,所以也许我需要创建一个人工解决方案最终使应用程序至少与方法1一样慢。

    3. 来源:

      (一些链接谈论方法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


      我对这件事真的很感兴趣,所以我将不胜感激任何意见:)

1 个答案:

答案 0 :(得分:5)

正如您链接的StackOverflow answer中所提到的,调用accept()的单个线程可能就是这样。您提到了有关锁定的问题,但是现在您会在Boost.LockfreeIntel TBB和其他地方找到无锁队列实现。如果您愿意,可以使用其中一个,但是您可以使用条件变量让工作线程休眠并在建立新连接时唤醒其中一个。