为了账号安全,请及时绑定邮箱和手机立即绑定

【九月打卡】第19天 go--channel学习(2)

标签:
Go

课程名称:深入Go底层原理,重写Redis中间件实战


课程章节:7-3,7-4,7-5


课程讲师:Moody


课程内容:

https://img1.sycdn.imooc.com/632c33d900019fe307141327.jpg

channel发送的情形

◆直接发送

  • 从队列里取出一个等待接收的G,无需先进入缓存

  • 将数据copy到接收的协程变量中

  • 唤醒G 开始工作

◆放入缓存

  • 获取可存入的缓存地址

  • 存入数据

  • 维护索引

◆休眠等待

  • 把自己包装成sudog

  • 将包装好的sudog放入sendq队列里去

  • 休眠协程并解锁

  • 被唤醒后,数据已经被取走了,无需加入缓存,只需要维护下其他的数据

channel接收的情形

◆有等待的协程G,从协程G接收

  • 判断有协程在sendq队列里等待,调用recv()

  • 判断此Channel里没有缓存

  • 直接从等待的协程G里取走数据,唤醒协程G

◆有等待的协程G,从缓存接收

  • 判断有G再发送队列等待,进入recv()

  • 判断此channel有缓存

  • 从缓存里取出一个G copy数据给接受者

  • 把sendq里面的协程取出一个到缓存

◆接收缓存

  • 判断sendq里面有没有等待的协程

  • 判断缓存

  • 从缓存里直接取走数据

◆阻塞接收--无缓冲区

  • 判断recvdq里面有没有等待接收的协程

  • 判断缓冲区是否存在

  • 包装成sodog,放入sendq队列,休眠


※ 非阻塞的channel

https://img1.sycdn.imooc.com//632c9d6f0001d0b613380492.jpg



点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消