前言
在博主的上篇博文中介绍了linux线程互斥的原因,并引入了互斥锁(Mutex)来解决问题,点击这里听互斥锁讲述它的的故事:linux线程互斥与同步(part1)—互斥锁(mutex)的原理及其实现机制
那么本篇博客就继续介绍关于linux线程互斥的另一个重要概念:条件变量(Condition Variable)
条件变量(Condition Variable)和互斥锁(Mutex)的“cp”关系
有句话叫“既生瑜,何生亮”,虽说互斥锁和条件变量都是为了维持线程间的互斥与同步。但他们可不是’瑜’和’亮’的关系。确切的说,他们俩是一对‘cp’。
首先,我们想象这样一个场景,有两个人,一个往盘子里放苹果;另一个从盘子中取苹果。
如果我们将盘子看作临界资源,把这两个人当作两个线程。加入互斥锁后,就形成了对盘子的互斥访问。
如果一个人拿到锁进入临界区放苹果,此时另一个人也来申请锁想拿苹果。那么这个人代表的线程就会被阻塞。在第一个人拿锁和解锁之前的整个过程中,第二个人只能一直申请访问互斥锁,直到第一个人解开锁。
线程进入临界区之前要先访问互斥锁,像上述例子中由于两个人的优先级不同,优先级高的线程不断重复“拿锁-进入临界区-放锁”的过程,且不做实质性的工作(占着茅坑不拉屎)。导致优先级低的线程得不到时间片来访问互斥锁。这样就会形成线程的“饥饿”问题。
为了解决这种问题,我们要保证对互斥锁的访问按某种顺序进行;使线程之间协同合作,这就是线程同步。
条件变量就是保证线程同步的一剂良药。
它提供了一种通知机制:在优先级高的线程放锁后立即通知别的线程取锁,若优先级高的线程想再次申请锁,只能在条件变量上挂起等待,这样就杜绝了优先级高的线程长时间霸占锁资源,实现线程间同步。
其实质是用变量的形式来表示当前条件是否成熟,标志资源状态。从而方便线程之间协作运行。
有了条件变量,上边的例子就会变成这样: