c++并发库condition_variable条件变量

condition_variable条件变量

一、引入头文件

#include<condition_variable>

二、wait等待

函数定义:

template<typename _Predicate>
      void
      wait(unique_lock<mutex>& __lock, _Predicate __p)
      {
	while (!__p())
	  wait(__lock);
      }

如果__p只是一个简单的布尔值,那么__p()实际上就是一个变量的值。而且,无论这个变量的值如何,!__p()都将会产生一个布尔值。这就导致了一个问题:无法在等待期间动态地检查条件,因为谓词只会在第一次调用时被评估,而之后每次调用都会得到同样的结果。

所以__p为一个可以调用的函数对象,将条件封装为一个可以调用的函数对象,以便在每次调用时都可以动态地评估条件。所以在这里使用lambda表达式返回bool值

condition_variable cv;
bool sub_run=false;
unique_lock<mutex> lock(mtx);
cv.wait(lock, [&]
                { return !sub_run; });

三、notify_all唤醒

//唤醒wait中等待的线程
cv.notify_all();	//之后wait函数会再一次执行wait函数中的lambda表达式

举例:

#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <chrono>
using namespace std;

int i = 0;
mutex mtx;
condition_variable cv;
bool sub_run = false;

void tf()
{
    while (i < 10)
    {
        unique_lock<mutex> lock(mtx);
        cv.wait(lock, [&]
                { return sub_run; });
        cout << "子线程:" << i << endl;
        i++;
        this_thread::sleep_for(chrono::milliseconds(10));
        sub_run = false;
        cv.notify_all();
    }
}

int main()
{
    thread th(tf);
    while (i < 10)
    {
        unique_lock<mutex> lock(mtx);
        cv.wait(lock, [&]
                { return !sub_run; });
        cout << "主线程:" << i << endl;
        i++;
        this_thread::sleep_for(chrono::milliseconds(10));
        sub_run = true;
        cv.notify_all();
    }
    th.join();
}

如果将cv.notify_all();注释掉

结果将会阻塞住

主线程:0
子线程:1

正常结果:

主线程:0
子线程:1
主线程:2
子线程:3
主线程:4
子线程:5
主线程:6
子线程:7
主线程:8
子线程:9
主线程:10
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值