如何在c ++中终止或停止分离的线程?

时间:2014-09-04 00:44:41

标签: c++ multithreading thread-safety

我有兴趣在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;
}

我之所以希望&#34;停止&#34; /&#34;终止&#34; globalThread()是因为valgrind列出这是一个&#34;可能丢失&#34;内存泄漏类型(152字节)。解决这个问题的最佳方法是什么?

4 个答案:

答案 0 :(得分:10)

没有规定可以阻止另一个线程;无论它是分离的还是可加入的。

停止线程的唯一方法是让线程从初始线程函数返回。

在这种特殊情况下,我建议进行以下更改:

  1. 不要拆卸线程。在main()中实例化它。
  2. 添加bool值和std::mutex,bool初始化为false
  3. 每次通过线程的内部循环,使用std::unique_lock锁定互斥锁,取bool的值,然后解锁互斥锁。解锁互斥锁后,如果bool为true,则跳出循环并返回。
  4. 在main()中,退出之前:锁定互斥锁,将bool标志设置为true,解锁互斥锁,然后加入线程
  5. 这并不完美,因为第二个线程最多需要5秒才能检查bool标志并返回。但是,这将是第一次。

答案 1 :(得分:1)

您可以降低到C ++标准以下并使用特定于操作系统的功能,例如在设置信号掩码时发送您自己的进程信号,以便它只传递给分离的线程 - 处理程序可以设置一个标记& #39;从您的主题中调查。如果你的主程序等待的时间长于轮询周期加一点,你可以猜测它应该终止;-P。相同的一般思想可以与任何其他信令机制一起使用,例如原子终止-asap标志变量。

或者,只作为最后的手段,有pthread_cancel和类似的。请注意,像这样的异步取消通常是一件非常危险的事情 - 您应该小心,您终止的线程可以在任何具有锁定/获取资源的代码中,或者您可能遇到死锁,泄漏和/或未定义的行为。例如,您的代码调用std::this_thread::sleep_for(std::chrono::seconds(5)); - 如果在间隔到期时要求操作系统进行回调,那么继续使用已终止线程的堆栈的函数会怎样?一个可以安全的例子是线程在你的应用程序中循环进行一些简单的数字运算。

如果你避免首先拆开线程,Sam的答案会提供替代文件......

答案 2 :(得分:1)

无法干净地关闭分离的线程。这样做需要等待清理完成,并且只有在线程可以连接时才能执行此操作。

例如,考虑线程是否持有另一个线程需要获取的互斥锁以便干净地关闭。干净地关闭该线程的唯一方法是诱导它释放该互斥锁。这需要线程的合作。

考虑线程是否已打开文件并对该文件保持锁定。中止线程将使文件锁定,直到进程完成。

考虑线程是否持有保护某些共享状态的互斥锁,并将该共享状态暂时置于不一致状态。如果终止该线程,则永远不会释放互斥锁,或者在受保护数据处于不一致状态时释放互斥锁。这可能会导致崩溃。

你需要一个线程的合作才能彻底关闭它。

答案 3 :(得分:0)

注意到“否”的直接答案没有帮助:

通常,您会看到类似于“使用自己的线程间通信”的答案

是在主线程和子线程之间共享原子布尔,还是通过OS方法向另一个线程发出信号。

当您希望独立线程死亡时,将重点转移到特定细节上可能会有所帮助,而不是“谁杀死了谁”。

https://en.cppreference.com/w/cpp/thread/notify_all_at_thread_exit

看看上面的代码示例可以帮助我解决我正在处理的问题(主线程模糊不清和儿童段错误),希望对您有所帮助。