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

2admgd59  于 2023-02-20  发布在  其他
关注(0)|答案(6)|浏览(335)

我对在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;
}

我之所以要“stop”/“terminate”globalThread()是因为valgrind列出了这是一个“可能丢失”类型的内存泄漏(152字节)。

ekqde3dh

ekqde3dh1#

没有停止另一线程的规定;不管是独立的还是可连接的。
停止线程的唯一方法是让线程从初始线程函数返回。
在这一特殊情况下,我建议作以下修改:
1.不要分离线程,在main()中示例化它。
1.添加一个bool值和一个std::mutex,bool值初始化为false
1.每次通过线程的内部循环时,使用std::unique_lock锁定互斥锁,获取bool的值,然后解锁互斥锁。解锁互斥锁后,如果bool是true,则跳出循环并返回。
1.在main()中,退出前:锁定互斥锁,将bool标志设置为true,解锁互斥锁,然后加入线程
这并不完美,因为第二个线程检查bool标志并返回需要5秒钟,但是这是第一步。

bogh5gae

bogh5gae2#

没有办法干净地关闭分离的线程。这样做需要等待清理完成,并且只有在线程可连接时才能这样做。
例如,如果一个线程持有一个互斥锁,而另一个线程需要获得该互斥锁才能干净地关闭,那么干净地关闭该线程的唯一方法就是诱导它释放该互斥锁,这需要线程的合作。
考虑线程是否已打开文件并锁定该文件。中止线程将使文件保持锁定状态,直到进程完成。
请考虑线程是否持有保护某些共享状态的互斥锁,并已将该共享状态临时置于不一致状态。如果终止线程,则互斥锁将永远不会释放,或者互斥锁释放时受保护的数据处于不一致状态。这可能会导致崩溃。
您需要一个线程的合作来彻底地关闭它。

6yoyoihd

6yoyoihd3#

你可以低于C++标准,使用特定于操作系统的函数,比如给你自己的进程发送一个信号,同时设置信号掩码,这样它就只被传递给分离的线程--一个处理程序可以设置一个从你的线程轮询的标志。相同的一般思想可以用于任何其它信令机制,诸如原子terminate-asap标志变量。
另外,也是最后的选择,pthread_cancel和类似的方法。注意,像这样的异步取消通常是一件非常危险的事情--你应该小心,你终止的线程不能在任何有锁定/占用资源的代码中,否则你可能会有死锁、泄漏和/或未定义的行为。例如,您的代码调用std::this_thread::sleep_for(std::chrono::seconds(5));-如果在间隔到期时请求操作系统回调,但之后要继续的函数使用已终止线程的堆栈,该怎么办?例如,如果线程在应用内的循环中执行一些简单的数字运算,则可以确保安全。
否则,Sam的回答记录了一个替代方案,如果您首先避免断开线程......

ej83mcc0

ej83mcc04#

注意到直接回答“不”没有多大帮助:
通常,您会看到类似于“使用您自己的线程间通信”的答案
无论是在主线程和子线程之间共享的原子bool,还是通过OS方法向另一个线程发送信号。
将重点转移到您希望分离线程何时终止的细节上,而不是“谁执行终止”,这可能会有所帮助。
https://en.cppreference.com/w/cpp/thread/notify_all_at_thread_exit
查看上面这样的代码示例有助于我处理我正在处理的问题(主线程模糊地死亡和子线程分段),我希望它对您有所帮助。

btqmn9zl

btqmn9zl5#

我认为最好的方法是创建信号处理程序

#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函数在代码中创建信号。查看链接。

wj8zmpe1

wj8zmpe16#

您可以通过指针设置中断循环的条件来终止分离的线程。
您还可以使用信号量等待该线程完成执行。

相关问题