从套接字选择中断

我有一个循环,基本上每隔几秒(超时后)调用它:

while(true){ if(finished) return; switch(select(FD_SETSIZE, &readfds, 0, 0, &tv)){ case SOCKET_ERROR : report bad stuff etc; return; default : break; } // do stuff with the incoming connection } 

因此,基本上每隔几秒(由tv指定),它会重新激活监听。

这是在线程B(不是主线程)上运行的。 有时我想从线程A(主线程)立即结束这个接受器循环,但似乎我必须等到时间间隔结束。

有没有办法从另一个线程中断选择函数,以便线程B可以立即退出?

最简单的方法可能是使用pipe(2)创建一个管道并将read end添加到readfds 。 当另一个线程想要中断select()只需向它写一个字节,然后消耗它。

是的,您创建了一对连接的套接字。 然后线程B写入套接字的一侧,线程A添加另一侧套接字以进行选择。 所以一旦B写入套接字A退出select,不要忘记从套接字读取该字节。

这是中断选择的最标准和最常用的方法。

笔记:

在Unix下,使用socketpair创建一对套接字,在Windows下它有点棘手,但是对于Windows socketpair Google搜索将为您提供代码示例。

难道你不能让超时足够短(比如10ms左右?)。

这些“只是创建一个虚拟连接”类型的解决方案似乎有点被黑了。 我个人认为,如果一个应用程序设计得很好,并发任务永远不会被强制中断,只需要工作人员经常检查(这也是boost.threads没有终止函数的原因)。

编辑本回答简历。 这很糟糕,但它可能有助于其他人理解为什么它是坏的,这在评论中解释。

您可以使用来自主线程的shutdown(Sock,SHUT_RDWR)调用来等待select select,这也将在超时之前退出另一个线程,因此您不需要等到超时到期。

干杯。 🙂