C++11 mutex unique_lock condition_variable 互斥锁 条件变量

创建项目再进行测试比较麻烦,可以使用这个在线编译器进行验证,快速方便
C++11在线编译器

mutex是互斥锁,互斥量
condition_variable是条件变量,条件变量也是被多线程访问,所以也需要使用互斥量,上锁后访问

std::mutex m;
void fun(){
  std::unique_lock<std::mutex> lck(m);//定义时会自动上锁
}
//离开函数fun作用域后,会自动析构并释放锁,当然也可以手动unlock


std::unique_lock<std::mutex> lck2(m, std::defer_lock);// 通过defer_lock来手动上锁
lck2.lock()

下面是一段condition_variable的代码,作一点我的注释
来源:https://cplusplus.com/reference/condition_variable/condition_variable/

注意cv.wait(lck)处,在线程被阻塞和唤醒时,分别会释放锁和重新获取锁,和pthread_cond_wait一致

// condition_variable example
#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
#define threadnum 14 //自行修改观察结果,线程释放锁必然在go释放锁之后出现,有些线程也会在go释放锁之后才上锁

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

void print_id (int id) {
  std::unique_lock<std::mutex> lck(mtx);//对mtx自动上锁
  std::cout<< "thread " << id<<" 上锁"<<std::endl;//如果对下面阻塞释放锁和获取锁有疑问的,可以将此行注释取消进行分析
  while (!ready) cv.wait(lck);//等待全局变量ready信号,线程阻塞在此,放弃cpu,在队列里等待cv的信号来唤醒,自动调用lck.unlock()释放锁
  //当被唤醒时,会重新获取锁,自动调用lck.lock()
  // ...
  std::cout << "thread " << id <<" 释放锁"<<std::endl;
}

void go() {
  std::unique_lock<std::mutex> lck(mtx);//上锁
  ready = true;//全局变量ready置为true
  cv.notify_all();//唤醒所有等待线程
  //离开该函数作用域,析构lck,并unlock该锁
  std::cout<<"go 释放锁"<<std::endl;
}

int main ()
{
  std::thread threads[threadnum];
  for (int i=0; i<threadnum; ++i)
    threads[i] = std::thread(print_id,i);//创建时就开始运行,但阻塞在cv处,等待信号

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

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

  return 0;
}
posted @ 2023-02-04 15:18  ecnu_lxz  阅读(82)  评论(0编辑  收藏  举报