我有一个循环,基本上每隔几秒(超时后)调用它:
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(主线程)立即结束这个接受器循环,但似乎我必须等到时间间隔结束..
有没有办法从另一个线程中断select函数,以便线程B可以立即退出?
答案 0 :(得分:11)
最简单的方法可能是使用pipe(2)
创建管道并将读取结尾添加到readfds
。当另一个线程想要中断select()
只是向它写一个字节,然后消耗它。
答案 1 :(得分:3)
是的,您创建了一对连接的套接字。然后线程B写入套接字的一侧,线程A添加另一侧套接字以进行选择。所以一旦B写入套接字A退出select,就不要忘记从套接字读取这个字节。
这是中断选择的最标准和最常用的方法。
注意:
在Unix下,使用socketpair
创建一对套接字,在Windows下它有点棘手,但谷歌搜索socketpair
会给你代码样本。
答案 2 :(得分:-1)
难道你不能让超时足够短(比如10ms左右?)。
这些“只是创建虚拟连接”的类型解决方案似乎有点被黑了。我个人认为,如果一个应用程序设计得很好,并发任务就不必强行中断,只需要经常检查工作者(这也是boost.threads没有终止函数的原因)。
编辑将此答案简历。这很糟糕,但它可能有助于其他人理解为什么它是坏的,这在评论中有解释。
答案 3 :(得分:-1)
你可以使用来自主线程的shutdown(Sock,SHUT_RDWR)调用来等待select select,这也会在超时之前退出你的另一个线程,所以你不需要等到超时到期。
欢呼声。 :)