次の簡単な例を考えてみましょう。
#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()
ますか?そうでない場合、それが存在しない技術的な理由はありますか?
編集:あいまいさを解消するために、シグナル/シグナル参照を通知/通知/通知に変更しました。