c ++中唯一锁,互斥和条件变量的关系

时间:2017-03-10 07:49:08

标签: c++ multithreading locking mutex condition-variable

您好我有以下代码:

// 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> lock(mtx);
  while (!ready) cv.wait(lock);
  // ...
  std::cout << "thread " << id << '\n';
}

void go() {
  std::unique_lock<std::mutex> lock(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();
  std::cout << "Finished!" << std::endl;

  return 0;
}

如果我删除main中函数调用go()的注释,我得到以下输出:

10 threads ready to race...
thread 0
thread 8
thread 1
thread 2
thread 4
thread 5
thread 3
thread 6
thread 7
thread 9
Finished!

我完全理解为什么我得到这个输出的一些流程。但是,我不明白为什么我不能打印&#34; 10个线程准备比赛......&#34;如果我注释掉main里面的go()函数调用。如果我理解正确,我没有通过调用go()来调用notify_all(),因此线程不会被唤醒,但为什么打印函数&#34; 10个线程准备好比赛...&#34;没有被调用过吗?

另外,请解释为什么我需要调用std :: unique_lock lock(mtx);里面的go()函数。谢谢你们!

BTW只是为了引用,我在http://www.cplusplus.com/reference/condition_variable/condition_variable/

得到了这个例子

1 个答案:

答案 0 :(得分:4)

标准输出被缓冲。这意味着每个输出操作不会单独发送到父进程,而是聚集在内存中并批量发送。这样做是为了最小化系统调用/进程间通信的开销 - 或者无论输出需要什么。

当缓冲区被填满时,它将被刷新,并且只有在刷新它时才会看到任何输出。显然10 threads ready to race...不足以填补缓冲区。

当程序结束,或者访问标准输入或使用std::flushstd::endl明确请求时,也会刷新缓冲区。

当你的程序无限期地等待其他线程(在死锁中)时,它将永远不会到达缓冲区被进一步填充并最终刷新的点。