2013-03-10 13 views
6

私はVisual Studio 2012とC++ 11を使用しています。この場合、std :: thread C++。より多くのスレッド同じデータ

void client_loop(bool &run) 
{ 
    while (run); 
} 

int main() 
{ 
    bool running = true; 
    std::thread t(&client_loop,std::ref(running)); 

    running = false ; 
    t.join(); 
} 

、スレッドtのループが終了したことがないが、私は明示的にfalserunningを設定します。私はこれが動作しない理由を理解しません。 runrunningの位置は同じです。私はrunningを単一のグローバル変数として設定しようとしましたが、何も起こりません。私はポインタ値を渡すことを試みたが、何もしなかった。

スレッドは同じヒープを使用します。私は本当に理解していない。誰でも助けてくれますか?それはrunning変数のデータレース(1つのスレッドが、別のスレッドがそれを読み、それを書き込み)を導入しているため

+0

プログラムの終了が早すぎて興味深いものを観察することができません。 –

+0

いいえ、私はこの例 "t.join()"で書くのを忘れていました.. :) –

+0

'running'を' volatile'に設定するとどうなりますか? – didierc

答えて

11

あなたのプログラムは、未定義の動作を持っています。

あなたがアクセスを同期するためにミューテックスを使用するか、またはrunningatomic<bool>を行う必要があります

#include <iostream> 
#include <thread> 
#include <atomic> 

void client_loop(std::atomic<bool> const& run) 
{ 
    while (run.load()); 
} 

int main() 
{ 
    std::atomic<bool> running(true); 
    std::thread t(&client_loop,std::ref(running)); 

    running = false ; 
    t.join(); 

    std::cout << "Arrived"; 
} 

は作業live exampleを参照してください。

+0

ありがとう、私は(愚かに)2番目のスレッドだけがデータを読み取る場合、予防策が必要ないと思った。私は "原子"変数を知りませんでした:しかし、今私は非常に満足しています。再びありがとう –

+0

+1私は今日何かを学んだ。 – didierc

+0

@MatteoGaleotti合理的なアーキテクチャーであっても(もちろんUBですが)、この無限ループは単に単純に最適化されたものではありませんでした。 –

0

constは、おそらくコンパイラのコードの表示には影響しません。シングルスレッドアプリケーションでは、値は変更されません(この特定のプログラムは無意味です)。マルチスレッドアプリケーションでは、アトミック型であるため、コンパイラは負荷を最適化できませんので、実際にはここに問題はありません。それは本当にスタイルの問題です。 mainが値を変更し、client_loopがその変更を探しているので、値がconstであると私は言っているようには思えません。

関連する問題