[英]How to wake or terminate a sleeping std::thread gracefully?
#include <thread>
#include <chrono>
using namespace std:
void f()
{
// Sleeping for a very long while
while (SOCKET s = accept(listening_socket, ...))
{
// ...
}
}
int main()
{
std::thread t(f);
DoSomething();
t.???(); /* What to place here to wake/terminate thread f? */
}
Under Win32, I can use TerminateThread()
to kill a thread. 在Win32下,我可以使用
TerminateThread()
杀死线程。 But what I want is a cross-platform method to do that. 但是我想要的是一种跨平台的方法来做到这一点。
How should I do that gracefully in C++? 我应该如何在C ++中优雅地做到这一点?
I would recommend sleeping on a broadcast signal, semaphore, condition variable, or something instead of doing a blocking sleep. 我建议您在广播信号,信号量,条件变量或其他方面进行睡眠,而不要进行阻塞性睡眠。 Then your application just sets the signal and anyone that is sleeping will wake up and can exit.
然后,您的应用程序仅设置信号,任何正在睡眠的人都将醒来并可以退出。 It is a much cleaner solution since it gives the thread body a chance to cleanup whatever it might be doing - including releasing locks!
这是一个更干净的解决方案,因为它使线程主体有机会清理可能执行的所有操作-包括释放锁!
Response to Update 回应更新
In this specific case, call select
with a timeout before you call accept
. 在这种情况下,
select
调用带有超时的select
,然后再调用accept
。
The first issue comes from blocking mode socket accept, you should use non-blocking socket mode. 第一个问题来自阻塞模式套接字接受,您应该使用非阻塞套接字模式。
You can set a flag in while loop, for example: 您可以在while循环中设置一个标志,例如:
struct AcceptHandler
{
AcceptHandler()
: is_terminated(false)
{
}
void accept()
{
while(!is_terminated)
{
// select
// accept
cout << " in loop " << endl;
}
}
void terminate()
{
is_terminated = true;
}
private:
std::atomic<bool> is_terminated;
};
int main()
{
AcceptHandler ah;
std::thread t(std::bind(&AcceptHandler::accept, std::ref(ah)));
t.join(); /// this is just demo, it blocks here
ah.terminate();
return 0;
}
I used a flag(is_terminated) in the sample you could use condition variable(preferred way). 我在示例中使用了一个标志(is_terminated),您可以使用条件变量(首选方式)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.