我已经读过在一个线程中使用超过64个套接字是危险的(?)。但是 - 至少对我而言 - 非阻塞套接字用于避免复杂的线程事物。由于只有一个侦听器套接字,我应该如何将套接字拆分为线程并将其与select()一起使用?我应该为每个线程创建fd_sets还是什么?我应该如何将一个客户端分配给一个线程,因为我只能在CreateThread()的开头传递值?
答案 0 :(得分:4)
不,不,你在那里遇到了一些问题。
首先,处理许多套接字的理想方法是使用thread pool来完成套接字(客户端)前面的工作。
另一个线程,或两个(据我所知,实际上是CPU的数量),进行连接接受。
现在,当一个事件发生时,例如新连接,它将被分派到要处理的线程池。
其次,它取决于实际的实施和环境 例如,在Windows中有一些名为IOCP的东西。
如果你问我 - 不要打扰较低的实现,而是使用BOOST::ASIO或ACE等框架。
我个人喜欢ASIO。关于这些框架的最好的事情是它们通常是跨平台的(nix,Windows等)。
所以,我的回答有点宽泛,但我认为在深入研究代码/手册/实现之前,请考虑这些事实。
祝你好运!答案 1 :(得分:1)
嗯,你读过的是错的。许多功能强大的单线程应用程序都是使用非阻塞套接字和高性能I / O解复用器编写的,如epoll(4)
和kqueue(2)
。它们的优点是您可以预先设置等待事件,因此内核不必复制大量文件描述符,并且[重新]在每次轮询中设置大量内容。
如果您的主要目标是吞吐量,而不是延迟,那么线程就有优势。
查看可用技巧的概述:The C10K problem。
答案 2 :(得分:0)
处理许多套接字的“理想方式”并不总是 - 正如Poni似乎相信 - “有一个线程池。”
“理想”属于什么?编程是否容易?最佳表现?
由于他建议不要打扰“使用较低的实现”和“使用BOOST :: ASIO或ACE等框架”,我猜他的意思是易于编程。
如果他在Windows上有表现角度,他会推荐“称为IOCP的东西”。 IOCP是“IO控制端口”,它允许仅使用少量线程实现超快速IO应用程序(建议每个可用核心使用一个)。 IOCP应用程序围绕任何线程池等效运行循环,如果他曾使用它们编写代码,他就会知道它。 IOCP不会与线程池一起使用,而是与它们一起使用。
Linux中没有IOCP等效项。
在Windows上使用框架可能会缩短产品上市时间,但性能将远远低于选择纯IOCP实施时的性能。
性能差异应该考虑特定于操作系统的代码实现。如果选择通用解决方案,至少性能将"not have been given away accidentally."