我知道这个问题已被多次询问和回答,我知道结束线程的最佳方法是使用标志并在请求时退出线程函数。这也是我目前正在做的事情,但我的问题是线程函数运行了很长时间,所以有时候我需要等待几个小时才能结束线程。我的线程函数看起来像这样:
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
标志传递给所有这些函数并污染我的代码?
答案 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();
}