2017-08-31 43 views
0

在我的c + + 11项目中,我需要生成两个无限运行的线程。这里有一个例子:
C++:如何正确退出多线程程序

static vector<int> vec; 
static std::mutex mtx; 
static std::condition_variable cond; 
static bool done = false; 
void f1() 
{ 
    while(!done) 
    { 
     // do something with vec and mtx 
    } 
} 

void f2() 
{ 
    while(!done) 
    { 
     // do something with vec and mtx 
    } 
} 

thread t1(f1); 
thread t2(f2); 

void finish(int s) 
{ 
    done = true; 
    // what should I do??? 
} 

int main() 
{  
    signal(SIGINT, finish); 
    t1.join(); 
    t2.join(); 
    return 0; 
} 

通常情况下,我不会停止或中止这一计划。但在例外的情况下,我认为我需要为ctrl-c做点什么,这是用来杀死程序的。但我不知道如何正确退出这个程序。

如果我是对的,t1t2可能会继续执行,甚至如果main返回0,所以我想我需要让他们脱离这样的:

void finish() 
{ 
    done = true; 
    t1.detach(); 
    t2.detach(); 
} 

然而,当我执行该程序并做ctrl-c,我得到一个错误:

terminate called after throwing an instance of 'std::system_error'

我发现this link,所以我想亲blem是相同的:mtx和/或cond已被销毁,而t1t2尚未完成。

那么我该如何正确杀死程序呢?或者我不需要处理信号ctrl-c,程序本身知道如何正确退出?

+0

没有看起来差不多吧。除了'done'可能应该是['std :: atomic'](http://en.cppreference.com/w/cpp/atomic/atomic)而不是简单的'bool'。如果您分离线程,则无法连接。 –

+0

并减轻您的后顾之忧:对于未绑定的线程,只有线程真正结束时,“join”函数才会返回。这意味着你的'main'函数不会结束(并且进程退出),除非两个线程都退出了。 –

+0

这种问题的一般规则是使用线程消毒剂。是你做的吗? – NoSenseEtAl

回答

1

done应该是std::atomic<bool>,或者无序的读取/写入不合法。

如果std::atomic<bool>::is_lock_free为真,访问原子变量仅在信号处理程序中是安全的。检查一下。如果不是这样,你的程序可能应该在main中中止一个错误。

当你.join(),你等待线程完成执行。除非线程完成,否则您不想退出main

总之,这样做:

static std::atomic<bool> done = false; 

(代码其余部分放在这里)

int main() 
{  
    if (!done.is_lock_free()) return 10; // error 
    signal(SIGINT, finish); 
    t1.join(); 
    t2.join(); 
}