Linux下的互斥锁和条件变量

Posted 西邮Linux兴趣小组

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux下的互斥锁和条件变量相关的知识,希望对你有一定的参考价值。

我们知道多个线程之间有很多内存资源都是共享的,灵活的同时也会造成一些问题,就是当两个线程都要使用同一个资源的时候,例如两个线程同时对一个全局变量进行赋值然后打印,就会出现同步问题,有可能线程2打印出来的结果实际上是线程1对其赋的值。因此,Linux提供了几种方法用来解决多线程同步问题,在这里主要探究一下互斥锁和条件变量之间的瓜葛。


互斥锁

互斥锁是通过锁机制来实现线程间同步的一种方法。在同一时刻它通常只允许一个线程执行一个关键部分的代码。

下面列举操作互斥锁的几个函数:

而互斥锁使用的常规操作无非是初始化锁 、上锁和解锁 ,最后使用完不要忘记清理锁。互斥锁一旦被上锁,就只能由对其上锁的线程进行解锁,也就是说“解铃还须系铃人”。


条件变量

条件变量是利用线程间共享的全局变量进行同步的一种机制。条件变量宏观上类似于if语句,只要符合一定条件就能执行某段程序。

同样的,列举条件变量相关的几个函数:

使用条件变量主要包括两个动作,一个等待使用资源的线程,等待“条件变量被设置为真”;另一个线程在使用完资源后,“设置条件为真”,这样就可以保证线程间的同步了。但是这样就出现一个关键问题,就是要保证条件变量能被正确的修改,条件变量就要被保护起来。而实际使用中,又用到互斥锁来对条件变量进行保护,在这里便产生了疑问,既然条件变量使用过程中需要使用到互斥锁,干嘛不直接使用互斥锁来保护要进行的操作? 


如果使用互斥锁,当一个线程首先锁定了一个互斥锁然后开始自己的操作,其他后面来的线程想再锁定这个锁就必须反复查询这个锁的状态,直到发现该锁被第一个线程释放,然后这个时候剩下的线程又开始一拥而上争夺这个锁,这样大量线程频繁的查询锁的状态,然后争夺锁,是一件比较消耗资源的事情。而引入条件变量,我们只是在线程A查询/修改条件变量的那个操作上设置了互斥锁,紧接着,我们就使用pthread_cond_wait()函数使线程A加入指定的条件变量的等待队列,此时该函数会使线程A挂起,在线程A挂起之前该函数还会释放指定的互斥锁,这时候该锁可以由其他线程(例如线程B)锁上,当然线程B在锁定该互斥锁之后也应该使用pthread_cond_wait()函数使其加入条件变量的等待队列,并再次释放该锁,后面当条件变量被pthread_cond_singal()激活后,线程A被唤醒,离开pthread_cond_wait()之前又会重新锁定指定的互斥锁,注意,此时虽然互斥锁被锁上,但是由于线程B此时被条件变量阻塞,处于休眠状态,并不会发生只有互斥锁的那种情况下反复检查互斥锁造成资源消耗的问题,当线程A干完活之后,使用pthread_cond_unlock()函数解开互斥锁,供后续使用。 


如此一来,便能够解决只有互斥锁解决同步问题时的弊端。


https://blog.csdn.net/fujie2017/article/details/76683933

(更多详细内容,点击左下角【阅读原文】)

以上是关于Linux下的互斥锁和条件变量的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中使用互斥锁和条件变量实现带有信号的监视器

UNIX网络编程:互斥锁和条件变量

使用 pthread、互斥锁和条件变量解决哲学家就餐问题

信号量,互斥锁,读写锁和条件变量的区别

信号量互斥锁和条件变量的区别

提升进程间共享互斥锁和提升共享互斥锁的进程间条件变量