在这个例子中,condition_variable如何工作?

时间:2016-12-13 09:42:22

标签: multithreading c++11

// condition_variable example
#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;
}

condition_variable如何在这里工作?它在线程加入之前调用“go()”,所以这是不是意味着没有线程在等待?它在“go()”中调用“notify_all()”,是否通过通知全部做了什么?

2 个答案:

答案 0 :(得分:2)

线程开始在threads[i] = std::thread(print_id,i);

上执行

每个线程将获取互斥锁,然后通过等待条件变量释放它。这会暂停该线程的执行。

运行go()时,它会唤醒所有线程,然后重新执行。 th.join()调用是在程序退出之前等待每个工作线程完成的主要方法。

请注意,只有设法获取锁定的线程(因此继续等待cv)才会得到通知,其他人将获得锁定,并看到准备就绪,绕过cv < / p>

答案 1 :(得分:2)

  

它呼叫&#34; go()&#34;在线程加入之前,这不意味着没有线程在等待吗?

不,这并不意味着。可能有任意数量的线程在等待,具体取决于哪些线程有机会执行并在go之前开始等待。当然,如果有多个硬件线程,那么go在任何线程开始等待之前就会通知它,但这不是必需的。

连接意味着调用连接的线程将在调用线程恢复之前等待被调用的线程结束。如果在加入后调用go,则程序永远不会完成,因为数组中的线程正在等待条件变量,并且主线程在设置变量之前等待其他线程结束。

  

它正在调用&#34; notify_all()&#34;在&#34; go()&#34;,是否通过通知所有人做了什么?

它通知可能正在等待条件变量的所有线程。如果没有线程在等待,那么没有线程会对通知作出反应。