C ++终止线程

时间:2015-08-28 07:20:50

标签: c++ multithreading kill terminate

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

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

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

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

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

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

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

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

1 个答案:

答案 0 :(得分:1)

在谷歌上搜索了一段时间后,我发现(并创建了)一个对我来说完全没问题的答案,尽管它只适用于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();
}