我有一个包含阻止recv()
调用的线程,如下所示:
{
while(1)
{
recv(socket, buffer, sizeof(buffer), 0);
}
}
现在我想做的是从另一个线程发出recv()
函数信号,使其退出阻塞状态。我从另一个讨论如何在Unix中执行此操作的问题中阅读了以下答案(How to let a thread which blocks on recv() exit gracefully?):
或者:
- 使用
setsockopt()
和SO_RCVTIMEO
设置读取超时,并在触发时检查状态变量以查看您是否已被告知 你自己停止阅读。- 如果您想要永久停止阅读套接字,请将其关闭,以便使用
shutdown(sd, SHUT_RD)
进行输入。这将导致recv()
返回 从现在开始为零。- 将套接字设置为非阻塞模式,并使用
醇>select()
超时告诉您何时阅读,采用相同的策略 状态变量如上面的(1)所述。然而,非阻塞模式引入 相当复杂的发送操作,所以你应该 更喜欢上面的(1)或(2)。您的伪代码缺少EOS和错误检查。我希望它没有 真的很像。
我对第一个和第三个解决方案不感兴趣,因为CPU可能会耗尽,根据我的测试,Windows不支持第二个解决方案(我是对的吗?)。那么还有另一种退出阻止recv()
的解决方案吗?
答案 0 :(得分:4)
阻止 recv()
仅在以下时退出:
读取数据。
读取超时(SO_RCVTIMEO)。
连接已关闭。
如果这些选项都不适合您,则必须在阻止模式下调用recv()
,直到您知道有等待阅读的内容,如select()
所报告的那样WSAAsyncSelect()
1}},或WSAEventSelect()
。
否则,将套接字逻辑重写为:
以非阻塞模式使用套接字。
将WSARecv()
或RIOReceive/Ex()
与重叠I / O或I / O完成端口一起使用。可以使用CancelIo/Ex()
取消I / O操作。