0

条件変数の使用方法を理解しています (cv オブジェクトは変数でも条件を示すものでもないため、このコンストラクトの名前は IMO です)。したがって、次のようにBoost.Threadで標準的に設定されたスレッドのペアがあります。

bool awake = false;
boost::mutex sync;
boost::condition_variable cv;
void thread1()
{
    boost::unique_lock<boost::mutex> lock1(sync);
    while (!awake)
        cv.wait(lock1);
    lock1.unlock();    // this line actually not canonical, but why not?
    // proceed...
}
void thread2()
{
    //...
    boost::unique_lock<boost::mutex> lock2;
    awake = true;
    lock2.unlock();
    cv.notify_all();
}

私の質問は: thread2 は本当にへの割り当てを保護する必要がありawakeますか? notify_all()電話で十分だと思います。操作およびチェック対象のデータが単純な「続行可能」フラグ以上のものである場合、ミューテックスに値が表示されますが、ここではやり過ぎのように見えます。

二次的な質問は、コード フラグメントで尋ねられるものです。「データの処理」ステップの前に、スレッド 1 のロックがロック解除されていることが Boost のドキュメントに表示されないのはなぜですか?

編集: たぶん私の質問は本当に: この種の待機を実装するための CV よりもクリーンな構造はありますか?

4

2 に答える 2

1

スレッド 2 は、アウェイクへの割り当てを保護する必要がありますか?

はい。あるスレッドからオブジェクトを変更し、同期せずに別のスレッドからそれにアクセスすると、未定義の動作が発生します。たとえそれがただのbool.

たとえば、一部のマルチプロセッサ システムでは、書き込みがローカル メモリにのみ影響する場合があります。明示的な同期操作がなければ、他のスレッドが変更を認識しない可能性があります。

Boost のドキュメントに、「データの処理」ステップの前にスレッド 1 のロックが解除されていることが表示されないのはなぜですか?

フラグをクリアする前にミューテックスのロックを解除すると、別のシグナルを見逃す可能性があります。

この種の待機を実装するための CV よりもクリーンな構造はありますか?

Boost と標準 C++ ライブラリでは、いいえ。条件変数は、任意の共有状態を処理するのに十分な柔軟性があり、この単純なケースでは特に複雑すぎないため、より単純なものは特に必要ありません。

より一般的には、セマフォまたはパイプを使用して、スレッド間で単純なシグナルを送信できます。

于 2012-07-18T18:04:43.090 に答える
1

正式には、両方のスレッドで確実にロックが必要です。いずれかのスレッドがオブジェクトを変更し、複数のスレッドがそれにアクセスする場合、すべての アクセスを同期する必要があります。

実際には、おそらくロックなしでうまくいくでしょう。notify_allが必要なフェンスまたはメンバー命令を発行して、メモリが適切に同期されるようにすることはほぼ確実です。しかし、なぜリスクを冒すのですか?

の不在に関してはunlock、それがスコープ付きロック パターンの要点です。unlockはオブジェクトのデストラクタにあるため、例外が通過した場合でもミューテックスはロック解除されます。

于 2012-07-18T18:15:17.623 に答える