如何在c++中终止或停止分离的线程
How to terminate or stop a detached thread in c++?
我对终止/停止/终止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;
}
我之所以想"停止"/"终止"globalThread(),是因为valgrind列出了这是一种"可能丢失"类型的内存泄漏(152字节)。处理这个问题的最佳方法是什么?
没有停止另一个线程的规定;无论是分离的还是可连接的。
停止线程的唯一方法是让线程从初始线程函数返回。
在这种特殊情况下,我建议进行以下更改:
- 不要拆开螺纹。在main()中实例化它
- 加上布尔值和
std::mutex
,布尔将初始化为false
- 每次通过线程的内部循环,使用
std::unique_lock
锁定互斥体,获取布尔值,然后解锁互斥体。在解锁互斥体之后,如果bool是true
,则中断循环并返回 - 在main()中,退出前:锁定互斥体,将bool标志设置为
true
,解锁互斥体,然后加入线程
这并不完美,因为第二个线程需要长达五秒钟的时间来检查bool标志并返回。但是,这将是第一步。
没有办法干净地关闭分离的线程。这样做需要等待清理完成,并且只有在线程是可连接的情况下才能这样做。
例如,考虑一下,如果线程持有另一个线程需要获取的互斥量,以便干净地关闭。干净地关闭该线程的唯一方法是促使它释放互斥对象。这需要线程的合作。
考虑线程是否打开了一个文件并锁定了该文件。中止线程将使文件处于锁定状态,直到进程完成。
考虑线程是否持有一个互斥锁,该互斥锁保护某个共享状态,并将该共享状态暂时置于不一致状态。如果终止线程,那么互斥锁将永远不会被释放,或者互斥锁将在受保护数据处于不一致状态的情况下被释放。这可能会导致崩溃。
你需要线程的配合才能干净地关闭它。
您可以低于C++标准并使用特定于操作系统的功能,例如在设置信号掩码的同时向自己的进程发送信号,使其仅传递给分离的线程-处理程序可以设置从线程轮询的标志。如果你的主例程等待的时间超过了轮询周期加上一点,你可以猜测它应该已经终止-P.同样的一般思想可以用于任何其他信号机制,例如原子终止asap标志变量。
或者,作为最后的手段,还有pthread_cancel
和类似的。请注意,像这样的异步取消通常是一件非常危险的事情——你应该小心,你终止的线程不能在任何资源被锁定/占用的代码中,否则你可能会出现死锁、泄漏和/或未定义的行为。例如,您的代码调用std::this_thread::sleep_for(std::chrono::seconds(5));
——如果在间隔到期时要求操作系统进行回调,但之后要继续执行的函数使用终止线程的堆栈,该怎么办?一个安全的例子是,如果线程在你的应用程序中的循环中进行一些简单的数字运算。
否则,如果你一开始就避免分离线程,Sam的回答记录了一个替代方案。。。。
注意到"否";帮助不大:
一般来说,你会看到答案类似于";使用你自己的线程间通信";
无论这是主线程和子线程之间共享的原子bool,还是通过操作系统方法向另一个线程发出信号。
将焦点转移到你希望一个分离的线程何时死亡的细节上,而不是"谁杀人",这可能会有所帮助。
https://en.cppreference.com/w/cpp/thread/notify_all_at_thread_exit
看上面这样的代码示例帮助我处理了我正在处理的问题(主线程模糊地死去,子线程分段),我希望它能帮助你。
我认为最好的方法是创建信号处理程序
#include <iostream>
#include <csignal>
using namespace std;
void signalHandler( int signum ) {
cout << "Interrupt signal (" << signum << ") received.n";
// cleanup and close up stuff here
// terminate program
exit(signum);
}
int main () {
// register signal SIGINT and signal handler
signal(SIGINT, signalHandler);
while(1) {
cout << "Going to sleep...." << endl;
sleep(1);
}
return 0;
}
https://www.tutorialspoint.com/cplusplus/cpp_signal_handling.htm这是我得到代码的地方。您也可以使用raise函数在代码中创建信号。签出链接。
您可以通过设置分离线程的条件来终止通过指针的循环。
您也可以等待该线程,直到它使用信号量完成执行。
- 为什么即使调用了析构函数,C++11 中的分离线程也可以执行
- 检查分离的线程是否还活着?
- 为什么分离线程没有得到输出消息
- 如何"stop"正在等待条件变量的分离线程?
- 线程::加入与分离
- C++ 11 线程在分离后会自动销毁吗?
- 分离的线程:在繁忙时销毁互斥锁 错误C++
- 分离线程然后让它超出范围(并使其仍在运行)是否安全?
- 自终止线程.使用联接或分离
- 为什么 std::call_once 在联接和分离的线程中的行为不同?
- 重用分离的线程
- 为什么线程分离时程序挂起
- 无法永远分离线程 c++
- 访问全局或静态对象的分离线程
- 为什么std::async与简单的分离线程相比速度较慢
- 如何在 Windows C++ 上分离线程
- c++中分离线程的资源释放
- c++分离线程在其关联对象被删除后继续工作
- 分离线程执行结束
- c++ 11线程是否提供了一种在主线程退出后分离线程继续的方法?