condition_variable

时间:2018-11-17 00:41:13

标签: c++

在下面的示例中,我不了解ready的目的。在此示例中,使用或不使用ready有什么区别?

#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;
}

2 个答案:

答案 0 :(得分:6)

原因是f1_macro_manual_2: 0.8535353535353535 可以在进行cv.wait(lck);调用之前返回 ,这是由于“虚假唤醒”引起的。您可以查看Spurious wakeups explanation sounds like a bug that just isn't worth fixing, is that right?,了解有关原因的更多信息。

因此,等待/通知线程使用一个附加的谓词(在这种情况下为notify_all)来指示是否已发出条件信号或该条件是否由于虚假唤醒而唤醒。

答案 1 :(得分:-1)

当它不是it("should catch the error", fakeAsync(() => { spyOn(service, "loadObject").and.returnValue(Promise.reject("test error")); spyOn(logService, "error"); // Might need to mock this method too load(); // One of these // flushMicroTasks(); // tick(); expect(logService.error).toHaveBeenCalledWith("test error"); })); ready为假)时,您将阻塞一个或多个线程,直到您将它们中的一个/全部调用并让它们完成工作为止。但是,当ready为true时,将不会阻塞任何线程。这很重要,因为如果没有ready标志,您可能会阻塞应该执行的线程,因此将没有任何信息让它再次运行(当您阻塞线程时,您必须通知它,否则它将永远等待)< / p>