C++11 并发编程系列(三):条件变量(condition_variable)

并发编程作为 C++11 系列的一个重大更新部分,值得我们去探究,并应用其提升程序的性能。本系列参考了其他一些文章,对 C++11 并发编程的一些要点进行了总结,并给出一些示例。

condition_variable 类介绍

std::condition_variable 是 C++11 多线程编程中的条件变量。

当 std::condition_variable 对象的某个 wait 类函数被调用的时候,它使用 std::unique_lock(通过 std::mutex)来锁住当前的线程,当前的线程会一直被阻塞(进入睡眠等待状态),直到有**其他的线程在同一个 std::condition_variable 对象上调用 notify 类函数来唤醒它。

std::condition_variable 对象通常使用 std::unique_lock<std::mutex> 来等待,如果需要使用另外的 lockable 类型,可以使用 std::condition_variable_any 类,本文后面会讲到 std::condition_variable_any 的用法。

首先来看一个简单的例子:

// condition_variable::notify_one
#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 printId(int id)
{
  std::unique_lock<std::mutex> lck(mtx);
  // 如果标志位不为true,则等待
  while(!ready)
  {
    // 线程被阻塞,直到标志位变为true
    cv.wait(lck);
  }
  std::cout << "thread: " << std::this_thread::get_id() << " id: " << id << "
";
}

void go()
{
  std::unique_lock<std::mutex> lck(mtx);
  // 改变全局标志位
  ready = true;
  // 唤醒所有线程
  cv.notify_all();
}

int main()
{
  std::thread threads[10];

  for (int i = 0; i < 10; ++i)
  {
    threads[i] = std::thread(printId, i);
  }
  std::cout << "create done.
" ;

  go();

  for (auto &t : threads)
  {
    t.join();
  }
  std::cout << "process done.
" ;
  return 0;
}
root@ubuntu:~/c++# ./cond2
create done.
thread: 281473284649424 id: 8
thread: 281473343398352 id: 1
thread: 281473335005648 id: 2
thread: 281473326612944 id: 3
thread: 281473318220240 id: 4
thread: 281473309827536 id: 5
thread: 281473301434832 id: 6
thread: 281473293042128 id: 7
thread: 281473276256720 id: 9
thread: 281473351791056 id: 0
process done.

在上面的例子中,10 个线程被同时唤醒,因此打印的时候是乱序的。值得注意的是 while(!ready),实际上,正常情况下,cv.wait 只会被调用一次,然后等待唤醒,因为线程在调用 wait() 之后就被阻塞了。但是通过一个 while 循环来判断全局标志位是否正确,这样可以防止被误唤醒,这也是条件变量中的常见写法。

https://murphypei.github.io/blog/2019/04/cpp-concurrent-3.html

原文地址:https://www.cnblogs.com/dream397/p/14649844.html