go runtime.GOMAXPROCS经验谈(lesson)

go runtime.GOMAXPROCS经验谈

最近碰到一个问题,在一个对实时性要求较高的项目中,用go语言编写的后台程序在连续io读写(比如读取udp包)时间隔不稳定,导致最后输出的视频流有抖动,画面出现马赛克。该项目会常态下同时启动60个以上协程同时读取udp包。调查后发现是go协程调度对这次项目产生了影响。

    先简述一下go调度机制。

    go程序运行时会默认启动和cpu核心数相等的协程队列,每个队列会绑定一个操作系统线程,然后按照调度算法排队执行协程。这个调度算法有2个特点。

    一:协程的切换时间片是10毫秒,执行10毫秒后后切换到下一个协程,把自己加到队列末尾。

    二:如果正在执行的协程没有遇到非内联函数调用,那就会一直执行这个任务,直到它自己结束。



    从以上go调度原理可以看出以下几点结论。

    一:如果不使用runtime.GOMAXPROCS(n)设置协程队列个数,默认只会开启和cpu核心数相同的线程来执行程序。

    二:如果碰到类似于io这种会产生cpu等待或者一次执行耗时比较长的任务,如果线程数有限,并发的协程却很多时(协程数超过线程数),这时这个任务会因为协程调度的关系被反复排队执行或者一次执行很长时间饿死其他协程,导致协程被执行的时间变长以及执行时机不稳定。



经过以上分析,尝试了调用runtime.GOMAXPROCS(n)来增加协程队列数(换言之增加了该程序的线程数),当n设为较大数值时,比如20,得到明显改善。



    结论:通过增加线程数,来减少协程调度,使用操作系统线程调度使各协程得到相对均匀的时间片去执行,提高执行效率,同时减少了抖动。
  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

^_^ 纵歌

工作中的经验分享

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值