可以在多个线程中使用 WSAEventSelect() 来增加套接字限制吗?

Posted

技术标签:

【中文标题】可以在多个线程中使用 WSAEventSelect() 来增加套接字限制吗?【英文标题】:Can WSAEventSelect() be used in multiple threads to increase sockets limit? 【发布时间】:2015-02-20 11:50:33 【问题描述】:

这个article 说如下:

Windows 事件机制(例如 WaitForMultipleObjects())只能 一次等待 64 个事件对象。 Winsock 2 提供 WSAEventSelect() 函数让您使用 Windows 的事件机制 等待套接字上的事件。因为它使用了 Windows 的事件 机制,您一次只能等待 64 个套接字上的事件。如果 你想一次等待超过 64 个 Winsock 事件对象,你 需要使用多个线程,每个等待不超过64个 插座。

这个说法正确吗?我想监控 300 个套接字以查看它们是否有待读取的数据,那么我可以只创建 5 个线程并使用WSAEventSelect() 来执行此操作吗?

【问题讨论】:

Please try doing background research before posting here. Windows Sockets 2.0: Write Scalable Winsock Apps Using Completion Ports @IInspectable 所以我的问题的答案是否定的,或者您的意思是 IOCP 是一种更好的方法? @joseph_m 请参阅我之前链接的问题this answer,它解释了如何绕过 64 个套接字限制。 对WaitForMultipleObjects 的一次调用仅限于MAXIMUM_WAIT_OBJECTS 对象。可扩展的网络应用程序通常使用I/O Completion Ports 编写。 【参考方案1】:

回答您的问题 - 是的,您引用的陈述是正确的。各种WaitFor 函数一次最多只能等待64 个对象。因此,要同时等待 300 个套接字事件,您必须等待 5 个线程,其中 4 个线程正在等待 64 个事件,而第 5 个线程正在等待 44 个事件。

如果您想编写可扩展套接字代码,则根本不应该使用可等待套接字事件。请改用 I/O 完成端口。您可以将多个套接字与单个 IOCP 句柄相关联,并让多个线程(最好每个 CPU 内核一个)等待来自该单个 IOCP 的通知。使用支持 IOCP 的套接字函数(WSAConnect()WSAAcept()WSARead()WSASend() 等)并让他们在工作完成时通知您。这允许您以最小的开销并行处理多个套接字。

更多详情请参考这篇文章:

Windows Sockets 2.0: Write Scalable Winsock Apps Using Completion Ports

【讨论】:

同一篇文章还谈到select()WSAEventSelect() 相同(即可以在多个线程中使用以增加套接字限制)。这个关于select() 的说法也正确吗? select() 在不同的平台上有不同的限制,但在 Windows 上,select() 默认一次限制为 64 个套接字。请参阅 winsock.hwinsock2.h 中的 FD_SETSIZE 定义。不过,您可以手动将FD_SETSIZE 重新定义为#include <winsock.h> 之前的某个其他值。但我不建议对大量套接字使用单个 select() 调用。如果你达到那么高,你可能需要重写代码。

以上是关于可以在多个线程中使用 WSAEventSelect() 来增加套接字限制吗?的主要内容,如果未能解决你的问题,请参考以下文章

WinSock WSAEventSelect 模型总结

三.Windows I/O模型之事件选择(WSAEventSelect )模型

windows下的IO模型之事件选择(WSAEventSelect)模型

WinSock WSAEventSelect 模型

winsock编程WSAEventSelect模型

如何映射 POSIX 的 select 和 Windows WSAEventSelect 的事件