mutex体现的是一种竞争,我离开了,通知你进来。

cond体现的是一种协作,我准备好了,通知你开始吧。
互斥锁一个明显的缺点是它只有两种状态:锁定和非锁定。而条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,它常和互斥锁一起配合使用。使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化。一旦其他的某个线程改变了条件变量,他将通知相应的条件变量唤醒一个或多个正被此条件变量阻塞的线程。这些线程将重新锁定互斥锁并重新测试条件是否满足。一般说来,条件变量被用来进行线程间的同步。
两个线程操作同一临界区时,通过互斥锁保护,若A线程已经加锁,B线程再加锁时候会被阻塞,直到A释放锁,B再获得锁运行,进程B必须不停的主动获得锁、检查条件、释放锁、再获得锁、再检查、再释放,一直到满足运行的条件的时候才可以(而此过程中其他线程一直在等待该线程的结束),这种方式是比较消耗系统的资源的。而条件变量同样是阻塞,还需要通知才能唤醒,线程被唤醒后,它将重新检查判断条件是否满足,如果还不满足,该线程就休眠了,应该仍阻塞在这里,等待条件满足后被唤醒,节省了线程不断运行浪费的资源。这个过程一般用while语句实现。当线程B发现被锁定的变量不满足条件时会自动的释放锁并把自身置于等待状态,让出CPU的控制权给其它线程。其它线程 此时就有机会去进行操作,当修改完成后再通知那些由于条件不满足而陷入等待状态的线程。这是一种通知模型的同步方式,大大的节省了CPU的计算资源,减少了线程之间的竞争,而且提高了线程之间的系统工作的效率。这种同步方式就是条件变量。
以上说明可能有点抽象,考虑这样的简单场景:通过伪代码说明。
A线程从队列中取元素,B线程往队列中存放元素。不考虑免锁的实现。需要一个mutex用来保护队列的一致性,避免两个线程同时操作队列破坏数据结构。
当队列为空的时候,A需要不断的探测队列状态 :
while(1)
{
if(队列为空)
休眠10s
else
{
加锁
取元素
解锁
}
}
这就有一个问题,可能在刚进入休眠时,B放入元素了,但仍然需要休眠完整个10s的时间。造成不必要的延迟。当然如果不sleep,也可以,但会造成不必要的CPU开销。使用基于条件变量的事件通知唤醒机制,就可以避免这些问题。
一旦B放入元素完成后就执行pthread_cond_signal(),当前阻塞的线程就会立即被唤醒开始干活儿。
while(1) {
pthread_mutex_lock();
pthread_cond_wait();
取元素;
pthread_mutex_unlock();
}
条件变量都用互斥锁进行保护,条件变量状态的改变都应该先锁住互斥锁,pthread_cond_wait()需要传入一个已经加锁的互斥锁,该函数把调用线程加入等待条件的调用列表中,然后释放互斥锁,在条件满足从而离开pthread_cond_wait()时,mutex将被重新加锁,这两个函数是原子操作。
可以消除条件发生和线程睡眠等待条件发生间的时间间隙。其他线程在获得互斥量之前不会察觉到这种改变,因为必须锁定互斥量才能计算条件。
总而言之,为了避免因条件判断语句与其后的正文或wait语句之间的间隙而产生的漏判或误判,所以用一个mutex来保证: 对于某个cond的包括(判断,修改)在内的任何有关操作某一时刻只有一个线程在访问。也就是说条件变量本身就是一个竞争资源,这个资源的作用是对其后程序正文的执行权,于是用一个锁来保护。
这样就关闭了条件检查和线程进入休眠状态等待条件改变这两个操作之间的时间通道,这样线程就不会有任何变化。
感觉可以总结为:条件变量用于某个线程需要在某种条件成立时才去保护它将要操作的临界区,这种情况从而避免了线程不断轮询检查该条件是否成立而降低效率的情况,这是实现了效率提高。。。在条件满足时,自动退出阻塞,再加锁进行操作。
以上是关于效率问题,此外互斥锁还有一个缺点就是会造成死锁。
例如线程A和线程B都需要独占使用2个资源,但是他们都分别先占据了一个资源,然后又相互等待另外一个资源的释放,这样就形成了一个死锁。
条件变量起到了阻塞和唤醒线程的作用,所以通常互斥锁要和条件变量配合。
为了解决以上问题,条件变量常和互斥锁一起使用,条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足。使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化。一旦其它的某个线程改变了条件变量,它将通知相应的条件变量唤醒一个或多个正被此条件变量阻塞的线程。这些线程将重新锁定互斥锁并重新测试条件是否满足。
以上就是小编为大家带来的浅谈互斥锁为什么还要和条件变量配合使用全部内容了,希望大家多多支持~
# 条件变量和互斥锁
# Java多线程并发编程(互斥锁Reentrant Lock)
# 详解Java多线程编程中互斥锁ReentrantLock类的用法
# Java互斥锁简单实例
# 详解java中的互斥锁信号量和多线程等待机制
# 互斥
# 死锁
# 不满足
# 加锁
# 的是
# 多个
# 这两个
# 再加
# 它将
# 为空
# 这是
# 就会
# 改变了
# 在这里
# 完成后
# 还不
# 其他的
# 能在
# 形成了
# 这就
相关文章:
制作网站哪家好,cc、.co、.cm哪个域名更适合做网站?
如何解决VPS建站LNMP环境配置常见问题?
Python多线程使用规范_线程安全解析【教程】
如何在万网开始建站?分步指南解析
网站制作公司排行榜,四大门户网站排名?
如何在腾讯云服务器快速搭建个人网站?
免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?
非常酷的网站设计制作软件,酷培ai教育官方网站?
内网网站制作软件,内网的网站如何发布到外网?
正规网站制作公司有哪些,目前国内哪家网页网站制作设计公司比较专业靠谱?口碑好?
在线制作视频网站免费,都有哪些好的动漫网站?
SQL查询语句优化的实用方法总结
建站之星Pro快速搭建教程:模板选择与功能配置指南
兔展官网 在线制作,怎样制作微信请帖?
如何在云主机上快速搭建多站点网站?
如何在万网主机上快速搭建网站?
济南企业网站制作公司,济南社保单位网上缴费步骤?
建站主机选虚拟主机还是云服务器更好?
湖北网站制作公司有哪些,湖北清能集团官网?
电视网站制作tvbox接口,云海电视怎样自定义添加电视源?
网站设计制作企业有哪些,抖音官网主页怎么设置?
详解jQuery停止动画——stop()方法的使用
重庆市网站制作公司,重庆招聘网站哪个好?
如何在建站宝盒中设置产品搜索功能?
洛阳网站制作公司有哪些,洛阳的招聘网站都有哪些?
再谈Python中的字符串与字符编码(推荐)
XML的“混合内容”是什么 怎么用DTD或XSD定义
网页设计网站制作软件,microsoft office哪个可以创建网页?
建站之星微信建站一键生成小程序+多端营销系统
桂林网站制作公司有哪些,桂林马拉松怎么报名?
宝塔面板如何快速创建新站点?
上海网站制作网页,上海本地的生活网站有哪些?最好包括生活的各个方面的?
网站制作大概要多少钱一个,做一个平台网站大概多少钱?
高防网站服务器:DDoS防御与BGP线路的AI智能防护方案
购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?
招贴海报怎么做,什么是海报招贴?
如何通过远程VPS快速搭建个人网站?
如何用景安虚拟主机手机版绑定域名建站?
北京营销型网站制作公司,可以用python做一个营销推广网站吗?
宁波自助建站系统如何快速打造专业企业网站?
网站建设制作需要多少钱费用,自己做一个网站要多少钱,模板一般多少钱?
h5在线制作网站电脑版下载,h5网页制作软件?
广州网站建站公司选择指南:建站流程与SEO优化关键词解析
为什么Go需要go mod文件_Go go mod文件作用说明
html制作网站的步骤有哪些,iapp如何添加网页?
建站之星代理商如何保障技术支持与售后服务?
建站主机默认首页配置指南:核心功能与访问路径优化
实现虚拟支付需哪些建站技术支撑?
C#怎么使用委托和事件 C# delegate与event编程方法
建站之星下载版如何获取与安装?
*请认真填写需求信息,我们会在24小时内与您取得联系。