C++ 终止线程

C++ terminate thread

我知道这个问题已经被问过和回答过很多次了,我知道结束线程的最好方法是使用标志并在线程函数结束时退出线程函数要求。这也是我目前正在做的,但我的问题是线程函数运行了很长时间,所以有时我需要等待几个小时直到线程结束。我的线程函数看起来像这样:

void threadfunction()
{
    while(!exitRequested)
    {
        doSomeWork();
        object1.doSomeWork();
        object2.doSomeWork();
        while(somecondition)
        {
            object3.doSomeWork();
        }
        object4.doSomeWork();
    }
}

这只是一个例子,实际上代码看起来要复杂得多。但我想证明的是,我调用了几个 class 方法,这些方法可能需要几个小时才能完成(每个函数)。

所以我现在正在做的是检查函数之间是否请求退出(例如 object1.doSomeWork();object2.doSomeWork(); 之间),但正如我所说,函数调用最多可以占用几个小时,所以我需要检查是否在这些功能中请求退出。为此,我需要将 exitRequested 标志传递给这些函数,但在我看来这看起来不太好,可能会有更好的解决方案。

我能想到的一个解决方案是抛出异常,创建这样的东西:

void threadfunction()
{
    try {
        while(!exitRequested)
        {
            ...
        }
    } catch (const ExitRequestException &e) {}
}

但是需要以某种方式引发异常。据我所知,我不能在一个线程中从另一个线程引发异常,对吗?

你有更好的解决方案吗?还是您认为我真的需要将 exitRequested 标志传递给所有这些函数并 污染 我的代码?

在谷歌搜索了一段时间后,我发现(并创建了)一个对我来说非常合适的答案,尽管它只适用于 pthreads。对于非 pthreads,我可以想象使用 here.

中描述的概念

那么我现在在做什么:我正在向工作线程发送信号。此线程在信号处理程序中处理自定义信号并引发异常。此异常在线程函数的外部出现。通过使用这个概念,我的优势在于抛出异常并展开堆栈,因此我可以关闭所有打开的资源。这是我完整的工作示例:

#include <thread>
#include <signal.h>
#include <unistd.h>
#include <iostream>

using namespace std;

//Custom exception which is used to stop the thread
class StopException {};

void sig_fun(int s)
{
    if(s == SIGUSR2)throw StopException();
}

void threadFunction()
{
    cout<<"Thread started"<<endl;
    try {
        while(true)
        {
            //Work forever...
            sleep(1);
        }
    } catch(const StopException &e) {
        cout<<"Thread interrupted"<<endl;
    }
    cout<<"Thread stopped"<<endl;
}

int main(int argc, char *args[])
{
    //Install Signal handler function
    signal(SIGUSR2, sig_fun);
    pthread_t threadObject;
    thread t([&threadObject]()
    {
        //Store pthread_t object to be able to use it later
        threadObject = pthread_self();
        threadFunction();
    });

    string temp;
    cout<<"Write something when you want the thread to be killed"<<endl;
    cin>>temp;

    //Send Signal to thread
    pthread_kill(threadObject, SIGUSR2);
    t.join();
}