Cond:条件变量源码解读
Cond条件变量
针对场景
应用于一组goroutine等待某一个条件,当条件为true时唤醒某一个或者所有的goroutine
源码解读
type Cond struct {noCopy noCopyL Locker //当观察(Wait方法)或者修改条件时加锁,Wait方法用锁是保护等待队列的并发安全notify notifyList //等待队列checker copyChecker //运行时检查是否存在复制使用
}// NewCond returns a new Cond with Locker l.
func NewCond(l Locker) *Cond {return &Cond{L: l}
}func (c *Cond) Wait() {c.checker.check() //检查是否存在复制使用t := runtime_notifyListAdd(&c.notify) //把调用的goroutine扔到等待队列c.L.Unlock() //解锁,所以调用Wait前要调用Lock,否则会panicruntime_notifyListWait(&c.notify, t) //阻塞等待(调用gopark)c.L.Lock() //加锁,所以最后一次等待被唤醒后要调用一次UnLock解锁
}func (c *Cond) Signal() {c.checker.check()runtime_notifyListNotifyOne(&c.notify) //唤醒队列头部的goroutine
}func (c *Cond) Broadcast() {c.checker.check()runtime_notifyListNotifyAll(&c.notify) //唤醒队列所有goroutine
}
使用示例
import ("fmt""sync""time"
)func condUseCase() {/*功能:十个运动员、一个裁判,裁判要等待十个运动员都准备就绪后才能开始比赛*/cond := sync.Cond{L: new(sync.Mutex),}ready := 0for i := 0; i < 10; i++ {i := igo func() {time.Sleep(time.Duration(i) * time.Millisecond)cond.L.Lock()ready++cond.L.Unlock()fmt.Printf("运动员%v号准备就绪\n", i)cond.Signal()}()}cond.L.Lock() //Wait方法会调用UnLock,所以要先Lock一下for ready != 10 {cond.Wait()println("裁判被唤醒")}cond.L.Unlock() //条件满足,最后一次Wait唤醒后会调用Lock,所以要UnLock一下println("所有运动员准备就绪")
}
常见踩坑
调用Wait前未加锁
因为Wait内部把当前goroutine扔到等待队列后会调用Unlock解锁,所以调用Wait前要调用Lock加锁,否则会panic
最后一次Wait返回后未解锁
Wait内部被唤醒后会调用Lock方法拿锁准备保护等待队列,但是最后一次Wait被唤醒后发现条件满足就不会操作等待队列后执行Unlock了,所以要在最后一个Wait返回后调用Unlock解锁
调用Wait后,没有检查条件是否满足就继续执行了
Wait方法返回不代表条件已经满足了,需要检查条件是否满足,如果满足继续执行,否则执行Wait继续等待
总结
使用Cond的场景大部分都可以使用Chan代替
Chan代替用法:创建一个没有buffer的chan,等待的goroutine从chan中获取元素阻塞,往chan中传入元素可以唤醒一个goroutine(Signal)、关闭chan可以唤醒所有goroutine(BroadCast)
使用Chan替代上面的示例:
func chanUseCase() {condChan := make(chan struct{})var mu sync.Mutexready := 0for i := 0; i < 10; i++ {i := igo func() {time.Sleep(time.Duration(i) * time.Millisecond)mu.Lock()ready++mu.Unlock()fmt.Printf("运动员%v号准备就绪\n", i)condChan <- struct{}{}}()}for ready != 10 {<-condChanprintln("裁判被唤醒")}println("所有运动员准备就绪")
}
Cond有三个特性Chan无法满足:
- Cond本身具有Locker,不需要创建额外的Locker保证条件的并发修改安全
- Cond可以调用多次BroadCast,但是Chan只能调用一次close
Cond:条件变量源码解读相关推荐
- PostgreSQL 源码解读(32)- 查询语句#17(查询优化-表达式预处理#2)
本节简单介绍了PG查询优化表达式预处理中常量的简化过程.表达式预处理主要的函数主要有preprocess_expression和preprocess_qual_conditions(调用preproc ...
- 源码解读Mybatis List列表In查询实现的注意事项
http://www.blogjava.net/xmatthew/archive/2011/08/31/355879.html 在SQL开发过程中,动态构建In集合条件查询是比较常见的用法,在Myba ...
- Java Review - Queue和Stack 源码解读
文章目录 Pre 概述 Queue Deque ArrayDeque 一览 构造函数 属性 方法 addFirst() addLast() pollFirst() pollLast() peekFir ...
- Spring5源码 - 05 invokeBeanFactoryPostProcessors 源码解读_2
文章目录 Pre 源码解读 总体流程 源码分析 细节解析 [初始化对应的集合 & 遍历用户自己手动添加的后置处理器] [调用实现了PriorityOrdered接口的BeanDefinitio ...
- Ubuntu 16.04下Caffe-SSD的应用(四)——ssd_pascal.py源码解读
前言 caffe-ssd所有的训练时的参数,全部由ssd_pascal.py来定义,之后再去调用相关的脚本和函数,所以想要训练自己的数据,首先要明白ssd_pascal.py各个定义参数的大体意思. ...
- php yii框架源码,yii 源码解读
date: 2017-11-21 18:15:18 title: yii 源码解读 本篇博客阅读指南: php & 代码提示: 工欲善其事必先利其器 yii 源码阅读指南: 整体上全貌上进行了 ...
- aqs java 简书,Java AQS源码解读
1.先聊点别的 说实话,关于AQS的设计理念.实现.使用,我有打算写过一篇技术文章,但是在写完初稿后,发现掌握的还是模模糊糊的,模棱两可. 痛定思痛,脚踏实地重新再来一遍.这次以 Java 8源码为基 ...
- Linux内核网络协议栈:udp数据包发送(源码解读)
<监视和调整Linux网络协议栈:接收数据> <监控和调整Linux网络协议栈的图解指南:接收数据> <Linux网络 - 数据包的接收过程> <Linux网 ...
- python库源码分析_python第三方库Faker源码解读
源码背景 Faker是一个Python第三方库,GITHUB开源项目,主要用于创建伪数据创建的数据包含地理信息类.基础信息类.个人账户信息类.网络基础信息类.浏览器信息类.文件信息类.数字类 文本加密 ...
最新文章
- ALV输出设置默认布局
- Qt Creator设置Qbs
- CharNet算法详解
- .propertie文件注释
- caffe-gpu ubuntu 安装_ubuntu16.04 cuda10.0 配置caffe gpu环境
- 别让for循环毁了你的程序(二)
- Python小白的数学建模课-B4. 新冠疫情 SIR模型
- 风险模型 - 变量筛选
- Nacos——Distro一致性协议(架构篇)
- 前后端分离-CRUD
- 视频教程-VR 游戏创业中的那些坑-其他
- laravel跨域问题
- APP下载链接点击量如何统计?
- R包之tm:文本挖掘包
- vue中用ref实现父子组件、孙组件、兄弟组件、非亲子孙组件互相调用的方法
- Excel转Json工具(支持GUI模式和命令行模式)
- 腾讯将开放多项无障碍AI技术,希望助力更多无障碍场景服务
- DataFountain-图书推荐系统
- 2019年中国经济四大看点
- caffe(ubuntu14.04)学习笔记1——运行MNIST数据集模型
热门文章
- bandizip修改压缩文件内容_即将对文件压缩软件Bandizip进行的更改
- 【4】 脑部MRI图像肿瘤分类级别
- ctfshow_萌新_萌新隐藏题
- 经典Java题目:输入一个数字,输出它的大写汉字(阿拉伯数字转汉字)
- 大家都在讲敏捷开发模型,但是落地又是迭代模型,迭代模型有哪些优势呢?
- TensorFlowX.Y核心基础与AI模型设计开篇
- 模式识别与机器学习(PATTERNnbsp;RECO…
- HOOK技术四-插件中Activity启动实战
- P3669 [USACO17OPEN]Paired Up S 贪心+双指针
- 短信验证-1基本的服务器环境搭建