2017-04-20 15 views
1

once_flag私は、この動作によって引き起こされるバグに遭遇しましたそれは次のようになりパット:呼び出し可能な関数がハングします::

01:

#include <mutex> 

std::once_flag onceFlag; 

int main(int argc, char* argv[]) { 
    std::call_once(onceFlag, 
     [](){ 
      std::call_once(onceFlag, 
       [](){} 
      ); 
     } 
    ); 

    return 0; 
} 

を私はcppreferenceでここに読んだものによると、(http://en.cppreference.com/w/cpp/thread/call_once)は、この先はstd最初の呼び出しとして、期待されるように::なcall_onceが実行を終了していないです

上記の の実行が正常に完了する前に、グループ内の呼び出しが返されません。つまり、 は例外によって終了しません。

なぜ上記の要件ですか?関数が呼び出される前にonce_flagを設定することはできませんでした。例外がスローされた場合はリセットされましたか?

+0

短い答え:委員会がそうすべきだと決めたので。 – Caleth

答えて

2

なぜ上記の要件ですか? 関数が呼び出される前にonce_flagを設定できませんでした。例外がスローされた場合はリセットされましたか?

よくない。あなたの提案では、once_flagが設定され、失敗した場合にリセットされます。競合状態が発生する可能性があります。このような状況を2つのスレッド、すなわちth1と​​で考えてみましょう。どちらも何らかの作業をしていますが、これは一度だけ行う必要があります。スレッドは、あなたの提案にあるようにonce_flagに依存しています。 th1は、内部がonce_flagで保護されています。​​はonce_flagの状態をチェックしており、そのpovタスクが完了しているため実行を停止します。 th1のタスクの実行中に例外がスローされ、th1 povから他のワーカーが実行を終了するので問題ありません。 th1が失敗し、once_flagが設定されていないため、once_flagが設定されているために​​が完了し、タスクが終了したと判断されたため、タスクは完了しません。

現在の要件では、このような不一致は起こりません。

関連する問題