可以在多个线程中使用 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.h
和 winsock2.h
中的 FD_SETSIZE
定义。不过,您可以手动将FD_SETSIZE
重新定义为#include <winsock.h>
之前的某个其他值。但我不建议对大量套接字使用单个 select()
调用。如果你达到那么高,你可能需要重写代码。以上是关于可以在多个线程中使用 WSAEventSelect() 来增加套接字限制吗?的主要内容,如果未能解决你的问题,请参考以下文章
三.Windows I/O模型之事件选择(WSAEventSelect )模型