我正在尝试实现一个使用 IOCompletionPort 从其客户端读取的服务器。我有一些与这个例子非常相似的东西。
如果我理解正确,这应该是我的设计:
- 【主线程】创建监听socket,绑定监听
- [主线程] 创建一个事件并使用 WSAEventSelect 将其附加到套接字接受信号
- [Accept Thread] 等待事件并接受客户端
- [Accept Thread] 当客户端连接时,使用 CreateIOCompletionPort 与它一起使用 IOCompletion 队列
- [Accept Thread] accept 线程调用第一个 WSARecv 并带有重叠参数
- 【Worker Threads】使用队列在WSARecv上实现leader-follower模式
在阅读了 WSARecv ( Here)之后,我发现如果数据准备好,WSARecv 可能会立即返回数据。这似乎有点奇怪,因为这意味着如果客户端发送速度足够快,工作人员可以在 WSARecv 上循环而不返回 IO 队列——这可能导致客户端饥饿......
在此我的问题是:
- 有没有办法“强制” WSARecv 不立即返回?我的意思是,100% 的时间返回 IO_PENDING?
- 如果不是 - 什么是正确的设计,针对可扩展性进行了优化?
这就是我使用 WSARecv 的方式:
flags = 0;
receiveResult = WSARecv(clientSocket, &(olStruct->Buffer), 1, &bytesReceived, &flags, (OVERLAPPED*)olStruct, NULL);
olStruct 是 OVERLAPPED 结构的扩展。
EDIT:
I ended up reposting what I got from WSARecv using PostQueuedCompletionStatus. I'd love to hear other solutions though
See Answer