【问题标题】:std::condition_variable::wait() misunderstanding [duplicate]std::condition_variable::wait() 误解[重复]
【发布时间】:2021-08-11 07:47:25
【问题描述】:

为什么必须使用while()std::condition_variable::wait() 在这个code:

#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void print_id (int id) {
  std::unique_lock<std::mutex> lck(mtx);
  while (!ready) cv.wait(lck);
  // ...
  std::cout << "thread " << id << '\n';
}

void go() {
  std::unique_lock<std::mutex> lck(mtx);
  ready = true;
  cv.notify_all();
}

int main ()
{
  std::thread threads[10];
  // spawn 10 threads:
  for (int i=0; i<10; ++i)
    threads[i] = std::thread(print_id,i);

  std::cout << "10 threads ready to race...\n";
  go();                       // go!

  for (auto& th : threads) th.join();

  return 0;
}

据我所知,如果 std::condition_variable::wait() 阻塞了当前线程,并且该线程正在等待暂停,直到另一个线程调用 notify..() 函数

【问题讨论】:

    标签: c++ multithreading wait


    【解决方案1】:

    为什么必须在 std::condition_variable::wait() 中使用 while()

    wait 可以返回 ready 是否为真。如果我们只想在ready 为真时继续,那么我们必须检查它,并继续等待以防万一。循环是一种方便的控制结构,用于重复操作直到满足条件。


    为什么 wait() 可能会看似虚假地返回

    因为标准说它可以:

    效果:

    • 以原子方式调用 lock.unlock() 并阻止 *this。
    • 解除阻塞时,调用lock.lock((可能在锁上阻塞),然后返回。
    • 当调用notify_­one() 或调用notify_­all()或虚假发出信号时,该函数将解除阻塞。

    【讨论】:

    • 这不是有点还原吗?从代码看来是不言而喻的。我想 OP 想了解为什么 wait() 可能会看似虚假地返回。
    • @Frank 我添加了更多细节。
    • 我已经回答了我的问题。那可能更令人满意 - stackoverflow.com/a/68776320/14934019
    • @MaxPopovsky 这个答案似乎没有提到线程可能被唤醒的第三种情况:虚假唤醒,这可能会在没有调用任何通知函数的情况下发生。
    • @MaxPopovsky 一个明确的解释:无论出于何种原因,线程都可能随时唤醒。解决方案:使用循环始终检查条件变量。
    猜你喜欢
    • 1970-01-01
    • 2022-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 2015-12-22
    • 2018-02-15
    • 1970-01-01
    相关资源
    最近更新 更多