再谈条件变量—从入门到出家


C语言--条件变量

条件变量是在线程中以睡眠的方式等待某一条件的发生;

条件变量是利用线程间共享的全局变量进行同步的一种机制:

  • 一个线程等待"条件变量的条件成立"挂起
  • 另一个线程使"条件成立"

条件变量的使用总是和一个互斥锁结合在一起;

**作用:**使用条件变量可以以原子方式阻塞线程,直到某个特定条件为真为止


我们一般使用的函数是:

#include <semaphore.h>
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr) ;
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_destroy(pthread_cond_t *cond);

案例一

代码:

#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>pthread_t t1;
pthread_t t2;pthread_mutex_t mutex;
pthread_cond_t cond;int i=0;void* Process1(void* arg)
{while(1){pthread_mutex_lock(&mutex);i++;if(i%5 == 0){pthread_cond_signal(&cond);}else{printf("this is Process1n");}pthread_mutex_unlock(&mutex);sleep(2);}
}void* Process2(void* arg)
{while(1){pthread_mutex_lock(&mutex);pthread_cond_wait(&cond,&mutex);printf("this is Process2,i=%dn",i);pthread_mutex_unlock(&mutex);sleep(2);}
}int main()
{pthread_cond_init(&cond,NULL);pthread_mutex_init(&mutex,NULL);pthread_create(&t1,NULL,Process1,NULL);pthread_create(&t2,NULL,Process2,NULL);pthread_join(t1,NULL);pthread_join(t2,NULL);return 0;
}

结果:

root@iZuf67on1pthsuih96udyfZ:~/C++/C++_test/Progress/cond# ./test1
this is Process1
this is Process1
this is Process1
this is Process1
this is Process2,i=5
this is Process1
this is Process1
this is Process1
this is Process1
this is Process2,i=10
this is Process1
this is Process1
^C

通过条件变量来控制线程的输出;


上述是在C语言中使用条件变量对线程进行一个控制,在C++中,在标准库中也提供了同样的机制,使用起来会比C语言的更加方便,但是原理还是一样的;

C++ 条件变量

C++标准库在< condition_variable >中

原则与C语言中类似

  • 包含< mutex >和< condition_variable >,声明一个mutex和一个condition_variable变量
  • 通知“条件已满足”的线程必须调用notify_one()或notify_all(),条件满足时唤醒处于等待中的一个条件变量;
  • 等待"条件被满足"的线程必须调用wait(),可以让线程在条件未被满足时陷入休眠状态,当接收到通知时被唤醒去处理相应的任务;

C++ 使用案例

#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <unistd.h>using namespace std;//全局条件变量
condition_variable cond;
mutex _mutex;
int count = 0;void fun1()
{while(1){count++;unique_lock<mutex>lock(_mutex);if(count%5 == 0){cond.notify_one();}else{cout<<"this is fun1,count="<<count<<endl;}lock.unlock();sleep(1);}
}void fun2()
{while(1){unique_lock<mutex>lock(_mutex);cond.wait(lock);cout<<"this is fun2,count="<<count<<endl;lock.unlock();sleep(2);}
}int main()
{thread t1(fun1);thread t2(fun2);t1.join();t2.join();return 0;
}

结果:

root@iZuf67on1pthsuih96udyfZ:~/C++/C++_test/Progress/cond# g++ -std=c++11 test2.cpp -o test2 -lpthread
root@iZuf67on1pthsuih96udyfZ:~/C++/C++_test/Progress/cond# ./test2
this is fun1,count=1
this is fun1,count=2
this is fun1,count=3
this is fun1,count=4
this is fun2,count=5
this is fun1,count=6
this is fun1,count=7
this is fun1,count=8
^C


到这里,基本回顾了C和C++中条件变量的用法,但是在实际应用中。又有设么用呢?

可能工作年限多的人,接触到的比较多,但是对于很多小白来说,或者刚毕业、刚参加工作的人来说,这点接触的就不是很多了,。这里来举一个例子说一下:

假如在某个项目中,需要用到的是多个线程,最简单的就是,用队列的时候,我们一边写一边读,总是要加锁的,但是,我们的线程就必须一直空转对队列进行检测是否有数据,但是这样往往会造成CPU使用率比较高,资源的浪费,这种情况下,我们就可以是使用条件变量,控制线程的循环,降低资源使用率;当然,也有很多场景值得去探索,也有很多技术可以解决这这个问题,希望大家一起探索前进;

问题思考

上面介绍了C和C++中的使用,但是其实还是有些疑问的

疑问:为什么pthread_cond_wait前加了锁,但是pthread_cond_signal还可以加锁?

首先看下我从网上找的一张图:

从这个图片中,我们发现了一个现象,pthread_cond_wait函数内存进行对锁的解锁,并且阻塞休眠操作,阻塞完成后,再次进行了加锁操作;也就是在pthread_cond_wait阻塞期间,pthread_cond_signal可以进行加锁和解锁操作,这里是不冲突的;

往期精彩文章汇总

  • muduo源码剖析学习总结
  • 掌握这个技能,你可以畅游github
  • C++ 简单对象池实现
  • 内存池设计与实现
  • 恭喜你!发现宝藏一份--技术文章汇总

想了解学习更多C++后台服务器方面的知识,请关注: 微信公众号:====CPP后台服务器开发====


冰冻三尺,非一日之寒,水滴石穿,非一日之功,愿我们一起加油努力~

调用另一个cpp的变量_再谈条件变量—从入门到出家相关推荐

  1. 再谈条件变量—从入门到出家

    再谈条件变量-从入门到出家 C语言--条件变量 条件变量是在线程中以睡眠的方式等待某一条件的发生: 条件变量是利用线程间共享的全局变量进行同步的一种机制: 一个线程等待"条件变量的条件成立& ...

  2. java线程条件变量_多线程同步条件变量(转载)

    最近看<UNIX环境高级编程>多线程同步,看到他举例说条件变量pthread_cond_t怎么用,愣是没有看懂,只好在网上找了份代码,跑了跑,才弄明白 #include #include ...

  3. frame中src怎么设置成一个变量_自动格式化打印变量HMLog介绍

    作者 | mao2020 来源 | 掘金,点击阅读原文查看作者更多文章 前言 在我初学iOS的时候,经常需要NSLog打印用于调试,有时候还需要打印多个变量: NSLog(@"xxxx fr ...

  4. MySQL数据库变量_数据库参数_MySQL变量_系统变量_用户变量

    文章目录 MySQL 变量分类 系统变量 查看系统变量 设置系统变量 如何通过配置文件来设置变量值 通过命令行选项来设置变量值 动态设置全局级的系统变量 设置静态的系统变量 设置会话级的系统变量 引用 ...

  5. java 静态变量回收_浅谈静态变量的回收问题

    今天工作中遇到一个用于缓存数据到内存的静态变量Stringbuffer:当缓存数据大小达到5M的时候就把该缓存数据写到S3上:然后清空该缓存buffer;看了这段代码我觉得是不是有点问题:先贴大概的代 ...

  6. 总线制和多线制示意图_再谈总线制与多线制的区别

    再谈总线制与多线制的区别 作者:大鹏 日期:2019-04-29 07:25:58 浏览:3007 关于火灾自动报警系统总线制与多线制的问题(其实就消防其他一些报警.预警系统也存在,本质是一样的),笔 ...

  7. 环境变量_配置JAVA环境变量

    本文标识 :  J00001本文编辑 :  YiKi编程工具 :  IDEA阅读时长 :  3分钟 什么是环境变量?环境变量是在操作系统中一个具有特定名字的对象, 它包含了一个或者多个应用程序所将使用 ...

  8. java 修改源码_再谈给应用程序diy启动画面和java源代码补丁修改

    再谈给应用程序diy启动画面和java源代码补丁修改 2006-8-21 16:18 6365 再谈给应用程序diy启动画面和java源代码补丁修改 2006-8-21 16:18 6365 搞diy ...

  9. css 变量_如何将CSS变量用于动画

    css 变量 当我们在讨论中提到CSS时,我们通常将其称为愚蠢的语言. 一种声明性语言,缺乏逻辑和洞察力: 但这不是真实的现实. 多年来,开发人员一直渴望标准CSS中的变量,长期以来一直被诸如LESS ...

最新文章

  1. jenkins_使用Jenkins / Hudson远程API检查作业状态
  2. PAT甲级1029 Median:[C++题解]贪心、二路归并
  3. 实现本网站图片保护功能之加水印
  4. 怎么理解ubuntu中的软件包管理器apt和dpkg
  5. Axure RP Pro - 翻译 - Download下载 - Axure RP Pro 5.5.0.1955
  6. 算法不会,尚能饭否之集合(Set)
  7. python 面试必问,不会真的要打脸~
  8. centos7安装samba文件服务器,Centos7.7部署文件共享服务Samba
  9. nginx connect() to (13: Permission denied) while connecting
  10. ARM 指令集版本和ARM 版本
  11. cad图纸怎么看懂_教你如何快速看懂建筑施工图纸
  12. C语言文件操作FILE文件指针fopen文件打开操作
  13. 2019最佳硬盘:台式机和笔记本电脑的顶级硬盘
  14. 做互联网最重要的是希望! 【水木周平】
  15. 对电话号码进行格式校验、脱密、加密、解密、掩码等的操作介绍
  16. 第28章 确认(Consent) - Identity Server 4 中文文档(v1.0.0)
  17. 【程序人生】春满人间
  18. AI原创生成器1.3版-9大改动
  19. shardingsphere: SpringBoot整合shardingjdbc实现读写分离
  20. python如何将txt文本导入excel实例

热门文章

  1. Android 实现选中与非选中样式效果
  2. mpvue 从零开始 女友的发带 2 window中设置
  3. mongoose 分页查询
  4. java sql 结果_Java中的SQL结果集
  5. 图数据库neo4j安装、neo4j使用
  6. java solr_通过Java访问Solr服务实例及相关配置
  7. java io流文件损坏_java使用io流下载.docx. xlsx文件,出现文件损坏提示
  8. n个数里找出前m个数(或者 从10亿个浮点数中找出最大的1万个)
  9. java log4j 配置_Java:log4j与log4j.properties的配置说明
  10. 子集生成 --二进制法