我读过在一个线程中使用超过 64 个套接字是危险的(?)。但是 - 至少对我来说 - 非阻塞套接字用于避免复杂的线程事情。由于只有一个侦听器套接字,我应该如何将套接字拆分为线程并将它们与 select() 一起使用?我应该为每个线程创建 fd_sets 还是什么?我应该如何将客户端分配给线程,因为我只能在开始时使用 CreateThread() 传递值?
3 回答
不不不,你有一些地方错了。
首先,处理许多套接字的理想方法是拥有一个线程池,它将在套接字(客户端)之前完成工作。
另一个或两个线程(据我所知实际上是 CPU 的数量)进行连接接受。
现在,当一个事件发生时,例如一个新的连接,它被分派到线程池进行处理。
其次,这取决于实际的实施和环境。
例如,在 Windows 中有一个叫做IOCP的东西。
如果你问我 - 不要为较低的实现而烦恼,而是使用诸如BOOST::ASIO或ACE之类的框架。
我个人喜欢ASIO。这些框架的最佳之处在于它们通常是跨平台的(nix、Windows 等)。
所以,我的回答有点宽泛,但我认为最好在深入研究代码/手册/实现之前考虑这些事实。
祝你好运!
“处理许多套接字的理想方法”并不总是 - 正如 Poni 似乎相信的那样 - “拥有一个线程池”。
“理想”与什么有关?是否易于编程?最棒的表演?
由于他建议不要打扰“较低的实现”和“使用诸如 BOOST::ASIO 或 ACE 之类的框架”,我猜他的意思是易于编程。
如果他从 Windows 的性能角度考虑,他会推荐“称为 IOCP 的东西”。IOCP 是“IO 控制端口”,它允许使用少量线程(建议每个可用内核一个线程)实现超快速 IO 应用程序。IOCP 应用程序围绕任何线程池等价物运行,如果他曾经使用它们编写代码,他会知道这些。IOCP 不与线程池一起使用,而是代替它们。
Linux 中没有等效的 IOCP。
在 Windows 上使用框架可能会加快产品的“上市时间”,但性能将与选择纯 IOCP 实现时的性能相差甚远。
性能差异使得应该考虑特定于操作系统的代码实现。如果无论如何选择通用解决方案,至少性能“不会被意外放弃”。