如何在 C++ 中终止或停止分离的线程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25655706/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to terminate or stop a detached thread in c++?
提问by codeshark
I am interested in terminating/stopping/killing a detached thread in c++. How can this be done?
我对终止/停止/终止 C++ 中的分离线程感兴趣。如何才能做到这一点?
void myThread()
{
int loop = 0;
while(true)
{
std::this_thread::sleep_for(std::chrono::seconds(5));
++loop;
}
}
void testThread()
{
std::thread globalThread(myThread);
globalThread.detach();
}
int main(void)
{
testThread();
for(unsigned int i=0; i < 1000; i++)
{
cout << "i = " << i << endl;
}
return 0;
}
The reason why I'd like to "stop"/"terminate" the globalThread() is because valgrind lists that this is a "possibly lost" type of memory leak (152 bytes). What is the best way to deal with this?
我想“停止”/“终止” globalThread() 的原因是因为 valgrind 列出这是一种“可能丢失”类型的内存泄漏(152 字节)。处理这个问题的最佳方法是什么?
采纳答案by Sam Varshavchik
There are no provisions to stop another thread; whether it's detached, or joinable.
没有停止另一个线程的规定;无论是独立的,还是可连接的。
The only way to stop a thread, is for the thread to return from the initial thread function.
停止线程的唯一方法是让线程从初始线程函数返回。
In this particular case, I would suggest the following changes:
在这种特殊情况下,我建议进行以下更改:
- Do not detach the thread. Instantiate it in main().
- Add a bool value, and a
std::mutex
, the bool gets initialized tofalse
- Each time through the thread's inner loop, lock the mutex using a
std::unique_lock
, take the bool's value, then unlock the mutex. After unlocking the mutex, if the bool wastrue
, break out of the loop, and return. - In main(), before exiting: lock the mutex, set the bool flag to
true
, unlock the mutex, then join the thread
- 不要拆线。在 main() 中实例化它。
- 添加一个 bool 值和 a
std::mutex
,bool 被初始化为false
- 每次通过线程的内部循环,使用 a 锁定互斥锁
std::unique_lock
,获取 bool 的值,然后解锁互斥锁。解锁互斥锁后,如果 bool 是true
,则跳出循环并返回。 - 在main()中,退出前:锁定互斥锁,设置bool标志为
true
,解锁互斥锁,然后加入线程
This is not perfect, since it will take up to five seconds for the second thread to check the bool flag, and return. But, this would be the first tep.
这并不完美,因为第二个线程检查 bool 标志并返回最多需要五秒钟。但是,这将是第一步。
回答by Tony Delroy
You could drop below the C++ Standard and use OS-specific functions, such as sending your own process a signal while setting the signal mask so it's delivered only to the detached thread - a handler can set a flag that's polled from your thread. If your main routine waits longer than the poll period plus a bit you can guess it should have terminated ;-P. The same general idea can be used with any other signalling mechanism, such as an atomic terminate-asap flag variable.
您可以低于 C++ 标准并使用特定于操作系统的功能,例如在设置信号掩码时向您自己的进程发送信号,以便它仅传递给分离的线程 - 处理程序可以设置从您的线程轮询的标志。如果您的主程序等待的时间比轮询周期长加上一点,您可以猜测它应该已经终止;-P。相同的一般思想可以与任何其他信号机制一起使用,例如原子终止尽快标志变量。
Alternatively, and only as a last resort, there's pthread_cancel
and similar. Note that async cancellation like this is a famously dangerous thing to do in general - you should be careful that the thread you terminate can't be in any code with locked/taken resources or you may have deadlocks, leaks, and/or undefined behaviour. For example, your code calls std::this_thread::sleep_for(std::chrono::seconds(5));
- what if that asks the OS for a callback when the interval expires, but the function to continue to afterwards uses the terminated thread's stack? An example where it can be safe is if the thread's doing some simple number crunching in a loop within your app.
或者,仅作为最后的手段,有pthread_cancel
和类似的。请注意,像这样的异步取消通常是一件众所周知的危险事情 - 您应该小心,您终止的线程不能在任何具有锁定/占用资源的代码中,否则您可能会出现死锁、泄漏和/或未定义的行为. 例如,您的代码调用std::this_thread::sleep_for(std::chrono::seconds(5));
- 如果在间隔到期时要求操作系统进行回调,但随后继续执行的函数使用终止线程的堆栈,该怎么办?一个可以安全的示例是线程是否在您的应用程序中循环执行一些简单的数字运算。
Otherwise Sam's answer documents an alternative if you avoid detaching the thread in the first place....
否则,如果您首先避免分离线程,Sam 的回答会记录另一种选择......
回答by David Schwartz
There is no way to cleanly shutdown a detached thread. Doing so would require waiting for the cleanup to complete, and you can only do that if the thread is joinable.
没有办法干净地关闭分离的线程。这样做需要等待清理完成,并且只有在线程可连接时才能这样做。
Consider, for example, if the thread holds a mutex that another thread needs to acquire in order to cleanly shut down. The only way to cleanly shut down that thread would be to induce it to release that mutex. That would require the thread's cooperation.
例如,考虑一下线程是否持有另一个线程需要获取的互斥锁,以便彻底关闭。干净地关闭该线程的唯一方法是诱导它释放该互斥锁。这需要线程的合作。
Consider if the thread has opened a file and holds a lock on that file. Aborting the thread will leave the file locked until the process completes.
考虑线程是否打开了一个文件并持有该文件的锁。中止线程将使文件保持锁定状态,直到进程完成。
Consider if the thread holds a mutex that protects some shared state and has put that shared state temporarily into a inconsistent state. If you terminate the thread, either the mutex will never be released or the mutex will be released with the protected data in an inconsistent state. This can cause crashes.
考虑线程是否拥有保护某些共享状态的互斥锁并将该共享状态暂时置于不一致状态。如果终止线程,则互斥锁将永远不会被释放,或者互斥锁将与处于不一致状态的受保护数据一起释放。这可能会导致崩溃。
You need a thread's cooperation to cleanly shut it down.
您需要线程的合作才能干净利落地关闭它。