先贴一个condition_variable的讲解:https://en.cppreference.com/w/cpp/thread/condition_variable,很详细也很全面,但是是英文的,劝退了一部分英语不好的人(也包括我),但是借助翻译还是大概可以看下来的,而且里面的两个代码也很有代表性,使用的生产者消费者模式,推给大家。

condition_variable是一个类,搭配互斥量mutex来用,这个类有它自己的一些函数,这里就主要讲wait函数和notify_*函数,故名思意,wait就是有一个等待的作用,notify就是有一个通知的作用。主要用法这里就不再赘述了,简而言之就是程序运行到wait函数的时候会先在此阻塞,然后自动unlock,那么其他线程在拿到锁以后就会往下运行,当运行到notify_one()函数的时候,就会唤醒wait函数,然后自动lock并继续下运行。

当然wait还有第二个参数,这个参数接收一个布尔类型的值,当这个布尔类型的值为false的时候线程就会被阻塞在这里,只有当该线程被唤醒之后,且第二参数为true才会往下运行。

notify_one()每次只能唤醒一个线程,那么notify_all()函数的作用就是可以唤醒所有的线程,但是最终能抢夺锁的只有一个线程,或者说有多个线程在wait,但是用notify_one()去唤醒其中一个线程,那么这些线程就出现了去争夺互斥量的一个情况,那么最终没有获得锁的控制权的线程就会再次回到阻塞的状态,那么对于这些没有抢到控制权的这个过程就叫做虚假唤醒。那么对于虚假唤醒的解决方法就是加一个while循环,比如下面这样:

while (que.size() == 0) {

cr.wait(lck);

}

这个就是当线程被唤醒以后,先进行判断,是否可以去操作,如果可以再去运行下面的代码,否则继续在循环内执行wait函数。

补充一个小的知识点,上面所说的多个线程等待一个唤醒的情况叫做惊群效应(了解的不多,大家可以自己查一下)。

下面就贴一个生产者消费者模式的代码:

#include

#include

#include

#include

#include

#include

std::mutex mtx; // 全局互斥锁

std::queue que; // 全局消息队列

std::condition_variable cr; // 全局条件变量

int cnt = 1; // 数据

void producer() {

while(true) {

{

std::unique_lock<:mutex> lck(mtx);

// 在这里也可以加上wait 防止队列堆积 while(que.size() >= MaxSize) que.wait();

que.push(cnt);

std::cout << "向队列中添加数据:" << cnt ++ << std::endl;

// 这里用大括号括起来了 为了避免出现虚假唤醒的情况 所以先unlock 再去唤醒

}

cr.notify_all(); // 唤醒所有wait

}

}

void consumer() {

while (true) {

std::unique_lock<:mutex> lck(mtx);

while (que.size() == 0) { // 这里防止出现虚假唤醒 所以在唤醒后再判断一次

cr.wait(lck);

}

int tmp = que.front();

std::cout << "从队列中取出数据:" << tmp << std::endl;

que.pop();

}

}

int main()

{

std::thread thd1[2], thd2[2];

for (int i = 0; i < 2; i++) {

thd1[i] = std::thread(producer);

thd2[i] = std::thread(consumer);

thd1[i].join();

thd2[i].join();

}

return 0;

}

本文同步分享在 博客“Ch_zaqdt”(CSDN)。

如有侵权,请联系 support@oschina.cn 删除。

本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

c语言怎么定义一个条件变量,C++ 条件变量(condition_variable)相关推荐

  1. c51语言定义位变量,C51中定义一个可位寻址的变量LED访问P1口访问P1.1引脚的方法是 。...

    C51中定义一个可位寻址的变量LED访问P1口访问P1.1引脚的方法是 . 更多相关问题 铸造全冠颈部肩台通常为A.0.2-0.4mmB.0.03mmC.0.3mmD.0.5-0.8mmE.1.0mm ...

  2. 怎样设置一个函数C语言,C语言中怎样编写一个函数 如何在C语言中定义一个函数?...

    如何在C语言中定义一个函数?小编很想在你面前流泪最后却还是选择装作打个哈欠 为什么小编怎么定义函数都不正确呢? 总是说小编 表达语法错误在main函数中 小编们可以在头文件与main函数之间定义,并编 ...

  3. #include<stdio.h>int main(){ int QQ_num;//定义一个名为QQ_num的变量存放QQ号 char pet_name[10];//定义一个名为pet_name

    #include<stdio.h> int main(){int QQ_num;//定义一个名为QQ_num的变量存放QQ号char pet_name[10];//定义一个名为pet_na ...

  4. 如何定义一个布尔类型的成员变量

    一般情况下,我们可以有以下四种方式来定义一个布尔类型的成员变量: boolean success boolean isSuccess Boolean success Boolean isSuccess ...

  5. c语言学习-定义一个整型数组a[10],将数组a[10]中的10个元素按逆序重新存放

    定义一个整型数组a[10],将数组a[10]中的10个元素按逆序重新存放 程序流程图: 代码: #include<stdio.h> void main() { int a[10]; int ...

  6. C语言: 定义一个函数int isprime(int n),用来判别一个正整数n是否为素数,若为素数函数返回值为1,否则为0。在主函数中输入一个整数x,调用函数isprime(x)来判断这个整数x是

    原题: 定义一个函数int isprime(int n),用来判别一个正整数n是否为素数,若为素数函数返回值为1,否则为0.在主函数中输入一个整数x,调用函数isprime(x)来判断这个整数x是不是 ...

  7. C语言: 定义一个函数int isprime(int n),用来判别一个正整数n是否为素数。在主函数中输入两个正整数m和n(m>=1,n>m),统计并输出m和n之间的素数的个数以及这些素数的和。

    原题: 定义一个函数int isprime(int n),用来判别一个正整数n是否为素数.在主函数中输入两个正整数m和n(m>=1,n>m),统计并输出m和n之间的素数的个数以及这些素数的 ...

  8. C语言:定义一个函数max_min,求一组数据的最大值和最小值. 在主函数中输入n和n个数据,调用max_min函数求出最大最小值,然后在主函数中输出这n个数的最大值和最小值。(要求使用指针做)

    [问题描述]定义一个函数max_min,求一组数据的最大值和最小值. 在主函数中输入n和n个数据,调用max_min函数求出最大最小值,然后在主函数中输出这n个数的最大值和最小值.(要求使用指针做) ...

  9. C语言:定义一个数组,5个元素,从xiao到da排序

    注意逆序与倒序的区别 //定义一个数组,5个元素,从xiao到da排序:#include <stdio.h>int main(int argc,char const *argv) {int ...

最新文章

  1. 数据标注成人工智能核心高地,未来谁扛大旗?
  2. 【转】Matlab中特殊符号的写法
  3. [渝粤教育] 广东-国家-开放大学 21秋期末考试财务管理10164k2 (2)
  4. 高等组合学笔记(八):第一类Stirling数, 整数分拆
  5. My first project
  6. 几句话实现导航栏透明渐变 – iOS
  7. GIT更新一其中一个提交版本
  8. MySql存储引擎的比较及选择
  9. Excel导入Sql Server出现Null的解决方法
  10. noip2017普及组
  11. Hadoop_MapperContextInputSplitFileSplit源码浅析
  12. 打开虚拟机 电脑自动重启解决办法
  13. 智慧城市不是建设出来的,而是运营出来的
  14. 两性离子洗涤剂的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  15. 计算机表格求和求平均值公式,EXCEL怎么求和,还有求平均值?,excle求和平均
  16. 2017年中国高速公路运输监测报告
  17. 数据结构题集(严书)查找 常见习题代码
  18. iOS:iPhone手机分辨率、尺寸、导航栏尺寸、Tabbar尺寸对比(菜鸟教程)
  19. 更换6700机器人平衡缸两侧轴承操作分享
  20. 《自动控制原理》(胥布工版)习题2-21

热门文章

  1. 中国内鼻扩张器市场趋势报告、技术动态创新及市场预测
  2. 中国酒精拭子市场趋势报告、技术动态创新及市场预测
  3. 手机桌面没有计算机图标,手机桌面图标不见了,更改桌面图标的大小-
  4. 谷歌:开源捐赠需分成,否则下架!
  5. 谁决定了 IT 直男的价值
  6. 百密一疏,防不胜防,细数那些大型数据库建设过程中绕不开的坑
  7. 快速了解 Kafka 生产者的使用和原理
  8. 苹果市值突破2万亿美元;华为推出PC版HMS“擎云生态”;Android11将强制应用使用内置相机| 极客头条...
  9. 马云盖茨入选最伟大25名抗疫领袖;周鸿祎卸任360金服;Node.js 14发布 | 极客头条...
  10. Python 数据分析实战:经典的同期群分析