1

次の簡単な例を考えてみましょう。

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex mutex;
std::condition_variable cv;
bool cv_flag = false; // I'm talking about this flag here

void startThread1()
{
    std::cout << "thread 1 prints first\n";
    {
        // Set the flag (lock to be safe)
        std::unique_lock<std::mutex> lock(mutex);
        cv_flag = true;
    }
    cv.notify_one();
}

void startThread2()
{
    std::unique_lock<std::mutex> lock(mutex);
    if (!cv_flag)
    {
        cv.wait(lock);
    }

    std::cout << "thread 2 prints second\n";
}

int main()
{
    std::thread thread1(startThread1);
    std::thread thread2(startThread2);

    thread1.join();
    thread2.join();
}

ここでcv_flagは、スレッド 2 がロックされていないことを確認するために使用されwait()、スレッド 1 が既に で通知を送信している場合notify_one()。これがないと、スレッド 2 がロックされ、スレッド 1 が既に を呼び出しwait() た後notify_one()で、スレッド 2 が既に発生した何かを待機しているため、無期限にハングする可能性があります。

このようなコードは、cv_flag見逃した可能性のある通知を検出するためだけに使用されるコードをたくさん見てきました。

これは本当にこれを行う唯一の方法ですか?そして、最もクリーンでシンプルな?次のようなことができれば素晴らしいと思います。

std::mutex mutex;
std::condition_variable cv;
// no more need for cv_flag

void startThread1()
{
    std::cout << "thread 1 prints first\n";
    cv.notify_one();
}

void startThread2()
{
    std::unique_lock<std::mutex> lock(mutex);
    cv.wait_unless_already_notified(lock); // Unfortunately, this function doesn't exist

    std::cout << "thread 2 prints second\n";
}

のようなものはありwait_unless_already_notified()ますか?そうでない場合、それが存在しない技術的な理由はありますか?

編集:あいまいさを解消するために、シグナル/シグナル参照を通知/通知/通知に変更しました。

4

2 に答える 2

4

cv_flag見逃された可能性のある信号を検出するためだけに使用されます。

あなたの情報は不完全です。フラグの主な機能は、見逃した通知を検出することだけではありません (これはシグナルと同じではありません。Dietmar のコメントを参照してください) condition_variable。関数) cv.wait()cv.notify_*()そういえば、あなたのコード例は間違っています:

if (!cv_flag)
{
    cv.wait(lock);
}

それはwhileループでなければなりません:

while (!cv_flag)
{
    cv.wait(lock);
}

のようなものはありwait_unless_already_signaled()ますか?そうでない場合、それが存在しない技術的な理由はありますか?

すでに述べた偽のウェイクアップの可能性があるため、「実際の」イベントの状態を反映する別の変数、少なくともブール値のフラグが必要です単なるの代わりに)。もちろん、この要件により、提案されたものが役に立たなくなります。これは、それが存在しない理由を説明しています。condition_variablewhileifwait_unless_already_signaled()

于 2013-09-09T05:54:55.740 に答える