条件变量的做用是用于多线程之间关于共享数据状态变化的通讯。当一个动做须要另一个动做完成时才能进行,即:当一个线程的行为依赖于另一个线程对共享数据状态的改变时,这时候就可使用条件变量多线程
因此,经过生产线程经过唤醒消费线程时最好的方式。如今咱们考虑一种实现,消费线程在阻塞以前要先解锁,同时还要将本身的标识符放入一个地方,以便生产线程经过这个标识符来激活本身。这样看起来是没问题了,然而不要忘记了,线程之间是并发/并行的。消费线程可能刚完成解锁的操做,就被生产线程获取到了并开始执行,这时,由于消费线程还未挂起本身,来不及将本身的标识符保存在某个位置,因此生产线程不认为有正在等待的线程。这时,切换到消费线程后,消费线程将永远的等待下去,虽然队列中有产品。而生产线程由于队列中有产品可能也一直的等待下去,造成了死锁。
解决方法是必须让解锁、保存线程标识符、挂起这一系列操做成为原子操做。这中解决方案就是条件变量,因此不难想到使用条件变量的时候必需要“伴随”一个互斥量。
条件变量是与互斥量相关联的一种用于多线程之间关于共享数据状态改变的通讯机制。它将解锁和挂起封装成为原子操做。等待一个条件变量时,会解开与该条件变量相关的锁,所以,使用条件变量等待的前提之一就是保证互斥量加锁。线程醒来以后,该互斥量会被自动加锁,因此,在完成相关操做以后须要解锁。
条件变量老是和谓语相关,学过《离散数学》应该还记得谓语表达式吧。谓语是具备惟一真假值的句子。程序中,能够用谓语来描述当前线程须要的状态。若是该谓语值为假,须要使用条件变量等待。醒来以后,因为系统的并发性,通常须要再次判断谓语值是否为真,若是不为真,则再次使用条件变量进行等待。
互斥量是用来防止对不变量的破坏,换句话说,是用来规范线程对共享数据的竞争使用。而条件变量是用来对线程同步,即用来协调各个线程合做完成某个任务。好比:足球场上,两个足球队对一个球的使用叫作竞争,可使用“马赛回旋”这种“互斥量”对球加锁,防止被抢。而传球这个动做就是使用“条件变量”进行唤醒,它的做用是保证一个球队的各个成员能协做起来将球踢进对方的球门。
条件变量的关注对象是共享数据状态的变化,这一变化可使用谓语来描述。由于涉及到共享数据,因此须要互斥量。互斥量和条件变量的对应关系为1:N.就是说一个互斥量能够对应多个条件变量,一个条件变量只能对应一个互斥量。这个能够这样理解:由于共享数据有不少种状态,描述这些状态就须要多个谓语,因此须要用多个条件变量。
条件变量和谓语的对应关系通常最好为1:1.1:N或者N:1并非不能够,可是容易引发死锁和竞争问题,要特别注意。若1个条件变量对应于多个谓语时,唤醒应采用广播的方式而不是signal的方式。