一、条件变量的认识

(1)条件变量的引出:
各个线程访问共享资源,比如说共享资源是一个空资源,那么,各线程的访问其实都是无效访问,因此需要一个机制,首先阻塞线程,以免其错误访问,待条件满足时(比如 共享资源不为空了),告知各线程开始访问共享资源即,在不满足某种条件下,我希望代码阻塞一会,待满足某种条件后,再让各线程工作,所谓某种条件就是条件变量。
(2)条件变量不是锁!但条件变量能够阻塞线程。
(3)如何实现线程同步 :
与锁配合使用:条件变量(引起阻塞)+ 互斥锁(保护一块共享数据)。
(4)条件变量的两个动作:
条件不满足,阻塞线程;
条件满足,通知阻塞的线程开始工作 。
(5)条件变量的经典模型:生产者和消费者模型

二、条件变量的操作函数

条件变量函数的返回值都是:成功返回 0, 失败直接返回错误号

pthread_cond_t cond; // 定义一个条件变量(condtion)

(1)初始化一个条件变量
函数说明:

int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);

使用:

pthread_cond_init ( & cond, NULL);//参数 2 条件变量的属性,一般传 NULL

(2)阻塞等待一个条件变量
函数说明:

int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);

使用:

pthread_cond_t cond // 初始化后的条件变量
pthread_mutex_t mutex; // 初始化后的互斥锁
pthread_cond_wait(&cond, &mutex);

作用:
1)阻塞等待条件变量 cond(参数 1)满足
2.)释放已掌握的互斥锁,相当于 pthread_mutex_unlock(&mutex);
注意:前 2 步是原子操作
3)当被唤醒,pthread_cond_wait 函数返回时,解除阻塞
重新申请获取互斥锁 pthread_mutex_lock(&mutex);
此处的 3 个作用,其实本质是着“生产者消费者模型”的工作流程。如下图所示:

消费者去消费,即访问头结点,因此在访问头结点前,先加互斥锁,发现头结点为空,此时由于条件变量,消费者被阻塞在此(等待生产者生产) 【pthread_cond_wait() 作用 1】,
此时,生产者生产,但遇到了消费者加的互斥锁,按理说无法生产,因此,这里涉及【pthread_cond_wait() 作用 2】,会将消费者已掌握的互斥锁解开,这样就可以生产了,生产后,将互斥锁饥解开,提醒消费者,已解除阻塞,但此时,消费者所加的互斥锁已经解开了,因此,涉及【pthread_cond_wait() 作用 3】,当 pthread_cond_wait()被唤醒后,重新为消费者回复原上锁状态,解除阻塞后,消费者开始消费,当消费结束后,解锁,让其他消费者抢锁。
(3)解除阻塞,唤醒线程

int pthread_cond_signal(pthread_cond_t *cond); //唤醒 至少一个 阻塞在条件变量上的线程
int pthread_cond_broadcast(pthread_cond_t *cond); //唤醒 全部 阻塞在条件变量上的线程

(4)销毁条件变量

 int pthread_cond_destroy(pthread_cond_t *cond);

Linux学习之系统编程篇:条件变量(pthread_cond_init / wait / signal / broadcast / destroy)相关推荐

  1. Linux学习之系统编程篇:使用条件变量实现“生产者和消费者模型”

    #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h&g ...

  2. Linux学习之系统编程篇:使用信号量实现“生产者和消费者模型”

    模型中,最为关键的步骤是,在生产者回调函数中,未生产之前,消费者回调函数是阻塞的,阻塞方式是条件变量. 那么不使用条件变量,如何使用"信号量"实现阻塞呢? 答案是因为调用 sem_ ...

  3. Linux学习之系统编程篇:exec 函数族

    函数能力:"换核不换壳"(能够替换进程虚拟地址空间中.text 代码段). 作用:让父子进程执行不相干的操作. 效果:有一个运行的程序 A,在 A 中调用另一个程序 B,程序有父子 ...

  4. Linux学习之系统编程篇:ps 和 kill 命令以及父子进程间数据共享模式

    一.ps 和 kill 命令 1.ps 命令 常用方式: ps aux :查看正在运行进程信息(主要查 pid). ps ajx :更加详细(PID. PPID:父进程 id. PGID:进程组 id ...

  5. Linux学习之系统编程篇:对线程的基本认识

    (1)fork()后创建的子进程是父进程的拷贝,那么pthread_create,创建线程,创建的线程跟原进程有什么关系呢? fork 会通过拷贝产生新的虚拟地址空间(PCB 会变化),而 pthre ...

  6. Linux学习之系统编程篇:MMU(Memory Manager Unit 内存管理单元)

    一.虚拟内存地址 对应于上图的两端,其中 0 - 3G 是用户区 ,3 - 4G 是内核区.编码的内存地址都是虚拟地址. 在3G到4G之间是PCB 进程控制块.从3G到0依次为: (1)命令行参数 和 ...

  7. Linux学习之系统编程篇:实现线程分离

    函数: int pthread_detach(pthread_t thread); // 参数:线程 ID 最大特点: (1)子进程会自己回收 PCB,因此调用该函数之后,不需要调用 pthread_ ...

  8. Linux学习之系统编程篇:编写一个守护进程

    需求:写一个守护进程,每隔 2s 获取一次系统时间,将这个时间写入到磁盘文件 #include <stdio.h> #include <stdlib.h> #include & ...

  9. Linux学习之系统编程篇:守护进程(精灵进程、后台进程)

    一.背景 一般情况下,启动终端(shell),系统会创建一个会话(shell 进程是会长),经过后续各种操作,该会话中会存在多个进程组,每个进程组中也会有多个进程(父进程是组长),若此时关闭 shel ...

最新文章

  1. JAVA按钮设置组合快捷键
  2. 自己看着视频的理解:设计模式之abstractfactory模式(2)
  3. python在线课程-《Python程序设计与应用》在线课程使用说明
  4. 科普| 什么是图数据库?
  5. js判断时间两小时之内_js判断两个时间的大小
  6. 经典C语言程序100例之九二
  7. centos7安装mysql6_2018年第四周-在centos7安装mysql6
  8. 在.net中加载dll的一种错误问题原因及处理
  9. 网站部署到云服务器需要哪些文件,云服务器能部署哪些应用?怎么部署?
  10. CentOS7下Nginx 安装 Lua 支持
  11. 使用命令行 启动 各种服务(控制面板 开机启动项 注册表 等)
  12. jquery html 动态添加元素绑定事件
  13. android 系统宏定义,Android.mk宏定义demo【转】
  14. Go语言编程从入门到精通,数据类型
  15. zemax输出ies_基于ZEMAX的光学设计教程(第2版)
  16. esxi6.7.0最新版本下载
  17. mac日历显示国家节假日及补班日期
  18. python绘制指数函数图像及性质_python实现画出e指数函数的图像
  19. VCPKG安装opencv后VS2019无法找到viz.hpp
  20. 新手做电商直播带货怎么和快递合作谈价格

热门文章

  1. 对凸优化(Convex Optimization)的一些浅显理解
  2. 黑箱优化:大规模语言模型的一种落地方式
  3. 本周不容错过的的9篇NLP论文 | PaperDaily #21
  4. Codeforces 982 C. Cut 'em all! 图的遍历
  5. filter函数的用法_JavaScript中forEach和filter的用法和原理
  6. 02 | 服务治理:Nacos 如何实现微服务服务治理
  7. python面向对象继承_Python 面向对象 --- 继承
  8. Spring Boot——SpringMVC带URL前缀的静态资源解决方案
  9. Spring Boot——集成七牛云OSS对象存储SDK解决方案
  10. Visual C++——加载自定义光标