2017-08-31 6 views
0

私のC++ 11プロジェクトでは、無限に動作する2つのスレッドを生成する必要があります。ここに例があります:
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のために何かをする必要があると思う、それはプログラムを殺すために使用される。しかし、私はこのプログラムを適切にやめる方法を知らない。私が正しい場合mainは、だから私は、私は彼らがこのように切り離すにする必要があると思う0を返した場合でも、

t1t2は実行を続ける場合があります:

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は破壊されましたが、t1またはt2はまだ完了していません。

どうすればプログラムを正しく終了できますか?あるいは、信号ctrl-cを処理する必要はなく、プログラム自体は正しく終了するために何をすべきかを知っていますか?

+0

いいえ

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

(残りのコードがここに入ります):

要するに、これを行います。ただし、 'done'は普通の' bool'の代わりに '' std :: atomic''(http://en.cppreference.com/w/cpp/atomic/atomic)でなければなりません。スレッドを切り離すと、結合できなくなります。 –

+0

そして、あなたの心配を軽減するために:スレッドが終了していないスレッドの場合、スレッドが本当に終了するまで、 'join'関数は戻りません。つまり、両方のスレッドが終了していない限り、 'main'関数は終了しません(プロセスが終了します)。 –

+0

この種の問題の一般的な規則はスレッドサニタイザを使用することです。あなたはそれをやりました? – NoSenseEtAl

答えて

1

donestd::atomic<bool>である必要があります。または、順序付けされていない読み取り/書き込みは合法ではありません。

std::atomic<bool>::is_lock_freeがtrueの場合、アトミック変数へのアクセスはシグナルハンドラでのみ安全です。それを確認します。それが真でない場合、あなたのプログラムはおそらくmainというエラーで中止するはずです。

.join()とすると、スレッドの実行が完了するまで待機します。そして、スレッドが終了していない限り、mainを終了する必要はありません。ほとんど右に見える

int main() 
{  
    if (!done.is_lock_free()) return 10; // error 
    signal(SIGINT, finish); 
    t1.join(); 
    t2.join(); 
} 
関連する問題