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


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 Process1\n");}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=%d\n",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可以进行加锁和解锁操作,这里是不冲突的;

再谈条件变量—从入门到出家相关推荐

  1. 调用另一个cpp的变量_再谈条件变量—从入门到出家

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

  2. 再谈UI设计的入门与进阶

    设计是一门实践性很强的工作嗯.假如你的学习目标是要成为一名UI设计师的话,建议尽早找一份相关的工作开始做起.因为只有你进入到这个角色,实际的进行项目流程的时候你才能亲身感受到你所面临的具体问题是什么, ...

  3. c++ linux 线程等待与唤醒_Linux线程同步(互斥量、信号量、条件变量、生产消费者模型)...

    为什么要线程同步? 线程间有很多共享资源,都对一个共享数据读写操作,线程操作共享资源的先后顺序不确定,可能会造成数据的冲突 看一个例子 两个线程屏行对全局变量count++ (采用一个val值作为中间 ...

  4. Linux 线程学习之条件变量

    互斥锁:用来上锁. 条件变量:用来等待,当条件变量用来自动阻塞一个线程,直到某特殊情况发生为止.通常条件变量和互斥锁同时使用. 函数介绍: 1. 名称: pthread_cond_init 目标: 条 ...

  5. 判断sem信号量为零_Linux线程同步(互斥量、信号量、条件变量、生产消费者模型)...

    为什么要线程同步? 线程间有很多共享资源,都对一个共享数据读写操作,线程操作共享资源的先后顺序不确定,可能会造成数据的冲突 看一个例子 两个线程屏行对全局变量count++ (采用一个val值作为中间 ...

  6. boost条件变量使用

    C++ BOOST库 条件变量[多线程通信]机制 笔记 1相关理念 (1)类名 条件变量和互斥变量都是boost库中被封装的类. (2)条件变量 条件变量是thread库提供的一种等待线程同步的机制, ...

  7. c++11多线程编程同步——使用条件变量condition variable

    简述 在多线程编程中,当多个线程之间需要进行某些同步机制时,如某个线程的执行需要另一个线程完成后才能进行,可以使用条件变量. c++11提供的 condition_variable 类是一个同步原语, ...

  8. 再谈进程—从入门到出家

    再谈进程-从入门到出家 这段时间由于工作上用到几个比较基础的进程编程,却发现自己好久没有接触进程了,都狂忘了!不得不感慨几句:老了老了~~~ 趁着对进程的回忆,也总一个简单的总结,下次可以回头看看,也 ...

  9. C++多线程快速入门(三):生产者消费者模型与条件变量使用

    互斥锁完成 #include <iostream> #include <deque> #include <thread> #include <mutex> ...

最新文章

  1. jQuery插件开发 - 其实很简单
  2. Redux 的黑魔法
  3. javascript脚本实现浏览器自动点击(阿里员工秒杀月饼)
  4. java中JVM内存管理(1)
  5. centos+bond+bridge+docker(ssh容器)固定ip实现测试环境(一)
  6. python3用list实现栈
  7. 马斯克惹麻烦?特斯拉股票一夜暴跌12%,千亿市值蒸发
  8. mysql null 走索引_mysql 索引列为Null的走不走索引及null在统计时的问题
  9. linux之添加python环境变量
  10. 【Tyvj】1473校门外的树3 线段树/树状数组 区间修改+单点访问
  11. 文件怎么更新_iOS屏蔽更新描述文件以及超级详细安装方法分享
  12. hadoop运维笔记
  13. python(三):时间窗口
  14. 相机标定—— 张正友标定法(1)
  15. VS2015安装配置assimp和glm
  16. Win8笔记本不能正常关机或重启
  17. 网页视频倍速播放代码
  18. Browserslist: caniuse-lite is outdated. Please run: npx browserslist@latest --update-db
  19. android 盈利模式
  20. leetcode刷题第21天——1763,117,572

热门文章

  1. java list移除符合条件的元素_java List删除指定元素的三种方法
  2. POJ3704 括号匹配问题
  3. 秒速区分商家和个人,网商银行为小微商价定制合理贷款
  4. python画桃花_Python-补充要点+技巧
  5. Javascript中理解发布--订阅模式
  6. c++全套流水账——写点游戏?!
  7. 最新二级域名分发系统改版源码分享
  8. linux命令行下清空回收站
  9. Java图形界面简单代码
  10. MFC应用SkinMagic皮肤可视化包更换程序外观皮肤