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

【九月打卡】第13天 go的协程-协程的并发、协程饥饿

标签:
Go

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


课程章节:5-6 如何实现协程并发?


课程讲师:Moody


课程内容:

https://img1.sycdn.imooc.com//6325e2b30001438e09580766.jpg

  1. 因为协程在线程里是逐一执行的,所以,当一个协程执行时间特别长,就会阻塞当前的线程,使得线程无法执行其他的协程,而线程本身的p是包含有一个协程队列,该队列里的协程就会出现饥饿问题

  2. 为了避免时间过长导致的阻塞,会有一个方法使得协程有一个超时机制(切入时机),超时触发后,协程将会被重新放入等待队列,该协程的执行的栈帧,上下文将被保留

  3. 如果所有的线程都出现了协程队列已经满,且协程都比较耗时的情况,就会导致全局的协程队列中的协程无法进入到线程里面的情况。这就是全局饥饿问题。

  4. 全局饥饿的解决方式是,线程每切换61次协程,就从全局队列里取一个新的协程进来参与处理。

------------------------------------------

※ 切入时机

https://img1.sycdn.imooc.com//6325e5950001bbd215920977.jpg

  1. 主动挂起

    主动挂起是用的 gopark()方法,该方法会在末尾执行mcall方法,mcall方法会直接调用schedule(),这样协程就回到了g0栈,保存当前协程的信息( PC/SP存储到g->sched),当后续对当前协程调用goready函数时候能够恢复现场;用户不能直接调用runtime包里的gopark方法,但是可以通过time.sleep方法来间接调用gopark方法。

    https://img1.sycdn.imooc.com//6325ec530001b64716660981.jpg

  2. 系统调用完成时

    系统调用完成时是说,当我们想获取系统的一些硬件信息,需要调用系统底层的函数,比如netpoll这样的,那么在调用完成后,go会调用 exitsyscall方法,这个方法的底层依然是调用了mcall



点击查看更多内容
TA 点赞

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

评论

作者其他优质文章

正在加载中
PHP开发工程师
手记
粉丝
2
获赞与收藏
4

关注作者,订阅最新文章

阅读免费教程

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

100积分直接送

付费专栏免费学

大额优惠券免费领

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

举报

0/150
提交
取消