我正在编写一个并发TCP服务器,它必须使用’每个连接的线程’方法处理多个连接(使用线程池).我怀疑哪个是每个线程获得不同文件描述符的最佳方式.
我发现接下来的两种方法是最推荐的:
>一个主线程,它接受()所有传入的连接并将它们的描述符存储在数据结构上(例如:一个队列).然后每个线程都能从队列中获取fd.
>直接从每个线程调用Accept(). (推荐于Unix Network Programming V1)
我找到他们每个人的问题:
>在线程可以读取之前,必须锁定存储所有fd的静态数据结构(mutex_lock),因此在相当多的线程想要在同一时刻读取的情况下,我不知道多少时间会过去,直到所有人都能实现目标.
>我一直在读,有关同时接受()调用的Thundering Herd问题尚未在Linux上完全解决,所以也许我需要为它创建一个人工解决方案,最终会使应用程序至少像方法1.
资料来源:
(一些链接谈论方法2:does-the-thundering-herd-problem-exist-on-linux-anymore – 以及我发现的一篇文章(过时):linux-scalability/reports/accept.html
并且SO答案建议方法1:can-i-call-accept-for-one-socket-from-several-threads-simultaneously
我真的对此事感兴趣,所以我会很感激任何意见:)
最佳答案
正如您链接的StackOverflow answer中所提到的,调用accept()的单个线程可能就是这样.您提到了关于锁定的问题,但是现在您将在Boost.Lockfree,Intel TBB和其他地方找到可用的无锁队列实现.如果您愿意,可以使用其中一个,但是您可能只使用条件变量让工作线程休眠并在建立新连接时唤醒其中一个线程.