条件变量的作用是用于多线程之间关于共享数据状态变化的通信。当一个动作需要另外一个动作完成时才能进行,即:当一个线程的行为依赖于另外一个线程对共享数据状态的改变时,这时候就可以使用条件变量

假设没有条件变量,对于一个生产者消费者问题,消费线程在得知队列中没有产品时,将阻塞自己。生产线程给队列中放入产品,但是没有办法激活消费线程,而消费线程处于阻塞状态也没有办法自激活。如果消费线程使用忙等的方式,通过不断地查询来判断是否有产品将大量的浪费CPU时间。消费线程可以使用睡眠+查询的方式,即发现队列中没有产品时,sleep一段时间,然后再查询。问题是睡眠多长时间?时间太长,实时性不好,时间太短,还是浪费CPU时间。

所以,通过生产线程唤醒消费线程是最好的方式。现在我们考虑一种实现,消费线程在阻塞之前要先解锁,同时还要将自己的标识符放入一个地方,以便生产线程通过这个标识符来激活自己。这样看起来是没问题了,然而不要忘记了,线程之间是并发/并行的。消费线程可能刚完成解锁的操作,就被生产线程获取到了并开始执行,这时,因为消费线程还未挂起自己,来不及将自己的标识符保存在某个位置,所以生产线程不认为有正在等待的线程。这时,切换到消费线程后,消费线程将永远的等待下去,虽然队列中有产品。而生产线程因为队列中有产品可能也一直的等待下去,形成了死锁。

解决方法是必须让解锁、保存线程标识符、挂起这一系列操作成为原子操作。这种解决方案就是条件变量,所以不难想到使用条件变量的时候必须要“伴随”一个互斥量。

条件变量是与互斥量相关联的一种用于多线程之间关于共享数据状态改变的通信机制。它将解锁和挂起封装成为原子操作。等待一个条件变量时,会解开与该条件变量相关的锁,因此,使用条件变量等待的前提之一就是保证互斥量加锁。线程醒来之后,该互斥量会被自动加锁,所以,在完成相关操作之后需要解锁。

条件变量总是和谓语相关,学过《离散数学》应该还记得谓语表达式吧。谓语是具有唯一真假值的句子。程序中,可以用谓语来描述当前线程需要的状态。如果该谓语值为假,需要使用条件变量等待。醒来之后,由于系统的并发性,一般需要再次判断谓语值是否为真,如果不为真,则再次使用条件变量进行等待。

互斥量是用来防止对不变量的破坏,换句话说,是用来规范线程对共享数据的竞争使用。而条件变量是用来对线程同步,即用来协调各个线程合作完成某个任务。比如:足球场上,两个足球队对一个球的使用叫做竞争,可以使用“马赛回旋”这种“互斥量”对球加锁,防止被抢。而传球这个动作就是使用“条件变量”进行唤醒,它的作用是保证一个球队的各个成员能协作起来将球踢进对方的球门。

条件变量的关注对象是共享数据状态的变化,这一变化可以使用谓语来描述。因为涉及到共享数据,所以需要互斥量。互斥量和条件变量的对应关系为1:N.就是说一个互斥量可以对应多个条件变量,一个条件变量只能对应一个互斥量。这个可以这样理解:因为共享数据有很多种状态,描述这些状态就需要多个谓语,所以需要用多个条件变量。

条件变量和谓语的对应关系一般最好为1:1.1:N或者N:1并不是不可以,但是容易引起死锁和竞争问题,要特别注意。若1个条件变量对应于多个谓语时,唤醒应采用广播的方式而不是signal的方式。

本文出自 “相信并热爱着” 博客,请务必保留此出处http://hipercomer.blog.51cto.com/4415661/914841

条件变量基本概念和原理相关推荐

  1. Linux多线程同步------条件变量

    先来看下<Linux高性能服务器编程>中对条件变量的描述: 上述话可以总结为: 多线程中某一个线程依赖于另外一个线程对共享数据的改变时,就可以使用条件变量! 用消费者生产者的来理解条件变量 ...

  2. 《GO并发编程实战》—— 条件变量

    声明:本文是<Go并发编程实战>的样章,感谢图灵授权并发编程网站发布样章,禁止以任何形式转载此文. 我们在第6章讲多线程编程的时候详细说明过条件变量的概念.原理和适用场景.因此,我们在本小 ...

  3. 【C++】多线程互斥锁、条件变量

    我们了解互斥量和条件变量之前,我们先来看一下为什么要有互斥量和条件变量这两个东西,了解为什么有这两东西之后,理解起来后面的东西就简单很多了!!! 先来看下面这段简单的代码: int g_num = 0 ...

  4. 浅析linux下的条件变量

    一.条件变量 条件变量是用来等待线程而不是上锁的,条件变量通常和互斥锁一起使用.条件变量之所以要和互斥锁一起使用,主要是因为互斥锁的一个明显的特点就是它只有两种状态:锁定和非锁定,而条件变量可以通过允 ...

  5. Linux多线程开发-线程同步-条件变量pthread_cond_t

    1.条件变量的概念 一个线程A的执行需要另一个线程B来唤醒,否则A挂起等待.线程B可以产生线程A继续执行的信号.条件变量常用在共享数据状态变化的场景中,例如:生产则和消费者问题.POSIX线程库提供了 ...

  6. 对条件变量(condition variable)的讨论

    作者:王东 1.1       什么是条件变量和条件等待? 简单的说: 条件变量(condition variable)是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待某个 ...

  7. 信号量 互斥量 条件变量

    原文:https://blog.csdn.net/qq_32646795/article/details/78221005 本文打算写一些和锁有关的东西,谈一谈我对锁的原理和实现的理解,主要包含以下方 ...

  8. 非常精简的Linux线程池实现(一)——使用互斥锁和条件变量

    https://blog.csdn.net/kxcfzyk/article/details/31719687 线程池的含义跟它的名字一样,就是一个由许多线程组成的池子. 有了线程池,在程序中使用多线程 ...

  9. 机器学习基础图表:概念、原理、历史、趋势和算法

    四大会计师事务所之一的普华永道(PwC)发布了多份解读机器学习基础的图表,其中介绍了机器学习的基本概念.原理.历史.未来趋势和一些常见的算法.为便于读者阅读,机器之心对这些图表进行了编译和拆分,分三大 ...

最新文章

  1. 数据结构-图-遍历-搜索
  2. linux shell seq 序列生成命令 可用于for循环 简介
  3. SQLSERVER的三种备份模式
  4. 自动滚放的html,HTML5实现视频播放器随页面滚动固定页面右下角效果详解
  5. web前端数组处理之数组去重
  6. 析构函数与构造函数的调用
  7. 北向资金运作akshare
  8. 32 位的有符号整数_leetcode 7 整数反转
  9. java内存shell_Springboot 内存shell
  10. 比ISA更简单的监管利器,谈谈关于公司上网监管的一点事儿
  11. 剪映专业版 for Mac(全能好用的视频编辑工具)v1.0.11中文版
  12. Linux 下串口编程入门教程
  13. 把已经写好的Vue项目转成uni-app项目
  14. tvm relay inline pass的调研
  15. 记一次App异常kill分析处理
  16. input 搜索localStorage存储历史记录 删除历史记录
  17. idou老师教你学istio2:监控能力介绍
  18. lsa ospf的opaque_OSPF LSA类型详解
  19. Re-ID with Triplet Loss
  20. H5C3进阶——播放器

热门文章

  1. Java关键字注意事项
  2. 【A40i-Android7.1】---编译报错:drivers/soc/allwinner/pm/.pm_debug.o.cmd:457: *** missing separator. Stop
  3. 【goldengate】官方文档笔记三 Oracle GoldenGate 实时报表
  4. 项目html+sass
  5. 如何摆脱极域2016(及以下版本)的控制
  6. 3601lpk.dll劫持病毒分析
  7. 晶闸管静态参数测试系统
  8. 给硬件工程师的入门课-硬件开发流程
  9. ROS机器人 RIA-E100使用
  10. CMDB 腾讯云部分实现