非阻塞套接字多线程接收模型

Posted

技术标签:

【中文标题】非阻塞套接字多线程接收模型【英文标题】:Non-blocking sockets multi-threaded receive model 【发布时间】:2014-06-06 10:43:48 【问题描述】:

我正在开发一个用于学习目的的多线程服务器应用程序。我现在的问题是接收数据。第一次编写应用程序时,我使用了 WSAAsyncSelect,但我不喜欢它的工作方式(在我看来,窗口依赖很愚蠢,即使你隐藏了窗口。)。所以我重新编写了它,现在我有一个线程通过连接的客户端并检查是否有任何数据要接收并将其传递给工作线程。这适用于少量客户,但我认为对于大量客户可能会延迟其他客户太多。我读过的一个解决方案是为每个客户端设置一个线程,但存在线程限制。另一种解决方案是 IOCP ( Windows ),但我需要找到一个好的文档,因为我发现的示例有点太模棱两可了(我可能是这里的问题)

我在 Microsoft Visual Studio 2013 下使用 C/C++ 的语言(WinSock,但我想以多平台方式编写)

【问题讨论】:

我认为,zeromq guide 是您开始的正确位置。在那里,您将了解处理套接字、线程和异步性时的注意事项。 另一个很好的来源是Boost.Asio 文档 【参考方案1】:

如果一个线程足以处理所有客户端,请考虑使用 N 个线程并在可用线程之间分配客户端(例如通过散列或按接收顺序)。

关键是线程的总数(首先在你的进程中:polling+worker...而且在整个系统中)必须保持不变并且不超过处理资源的数量(CPUs/cores)

轮询线程和工作线程之间的区别是正确的方法。使用队列结构解耦,释放轮询线程以不受工作线程上运行的(任意)逻辑的阻碍来完成其工作(即轮询)。

【讨论】:

【参考方案2】:

在 Windows 上,IOCP 是可扩展异步 IO 的标准模型。它解决了你提到的所有问题。 It has a sane programming model (with a few API design errors). I believe there are self-contained samples. 要学习 IOCP,我会使用这种技术创建一个非常简单的聊天服务器,并尝试让它完全正确。

选择的缺点是它不能缩放(如你所说)。

如果您想要可移植性,请查看 Boost asio 等异步 IO 库。他们在所有现代平台上使用类似 IOCP 的模型。它们是回调驱动的。

【讨论】:

以上是关于非阻塞套接字多线程接收模型的主要内容,如果未能解决你的问题,请参考以下文章

非阻塞套接字轮询与阻塞套接字

27 Apr 18 GIL 多进程多线程使用场景 线程互斥锁与GIL对比 基于多线程实现并发的套接字通信 进程池与线程池 同步异步阻塞非阻塞

java同异步请求和阻塞非阻塞的区别

多路复用 阻塞/非阻塞IO模型 网络IO两个阶段

如何使 UdpClient 非阻塞

5种IO模型阻塞IO和非阻塞IO同步IO和异步IO