内容简介:这里说的 “golang 抢占式调度”,只是 goroutine 调度的一部分内容。个人对 go 的调度理解为:伪抢占 + working steal。Go在设计之初并没考虑将goroutine设计成抢占式的。用户负责让各个goroutine交互合作完成任务。一个goroutine只有在涉及到加锁,读写通道或者主动让出CPU等操作时才会触发切换。垃圾回收器是需要stop the world的。如果垃圾回收器想要运行了,那么它必须先通知其它的goroutine合作停下来,这会造成较长时间的等待时间。考虑一种
这里说的 “golang 抢占式调度”,只是 goroutine 调度的一部分内容。个人对 go 的调度理解为:伪抢占 + working steal。
起因
Go在设计之初并没考虑将goroutine设计成抢占式的。用户负责让各个goroutine交互合作完成任务。一个goroutine只有在涉及到加锁,读写通道或者主动让出CPU等操作时才会触发切换。
垃圾回收器是需要stop the world的。如果垃圾回收器想要运行了,那么它必须先通知其它的goroutine合作停下来,这会造成较长时间的等待时间。考虑一种很极端的情况,所有的goroutine都停下来了,只有其中一个没有停,那么垃圾回收就会一直等待着没有停的那一个。
抢占式调度可以解决这种问题,在抢占式情况下,如果一个goroutine运行时间过长,它就会被剥夺运行权。
于是,Go在1.2版中开始引入比较初级的抢占式调度。
总体思路
引入抢占式调度,会对最初的设计产生比较大的影响,Go还只是引入了一些很初级的抢占,并没有像操作系统调度那么复杂,没有对goroutine分时间片,设置优先级等。
只有长时间阻塞于系统调用,或者运行了较长时间才会被抢占。runtime会在后台有一个检测线程,它会检测这些情况,并通知goroutine执行调度。
目前并没有直接在后台的检测线程中做处理调度器相关逻辑,只是相当于给goroutine加了一个“标记”,然后在它进入函数时才会触发调度。这么做应该是出于对现有代码的修改最小的考虑。
sysmon
前面讲Go程序的初始化过程中有提到过,runtime开了一条后台线程,运行一个sysmon函数。这个函数会周期性地做epoll操作,同时它还会检测每个P是否运行了较长时间。
如果检测到某个P状态处于Psyscall超过了一个sysmon的时间周期(20us),并且还有其它可运行的任务,则切换P。
如果检测到某个P的状态为Prunning,并且它已经运行了超过10ms,则会将P的当前的G的stackguard设置为StackPreempt。这个操作其实是相当于加上一个标记,通知这个G在合适时机进行调度。
目前这里只是尽最大努力送达,但并不保证收到消息的goroutine一定会执行调度让出运行权。
morestack的修改
前面说的,将stackguard设置为StackPreempt实际上是一个比较trick的代码。我们知道Go会在每个函数入口处比较当前的栈寄存器值和stackguard值来决定是否触发morestack函数。
将stackguard设置为StackPreempt作用是进入函数时必定触发morestack,然后在morestack中再引发调度。
看一下StackPreempt的定义,它是大于任何实际的栈寄存器的值的:
// 0xfffffade in hex. #define StackPreempt ((uint64)-1314)
然后在morestack中加了一小段代码,如果发现stackguard为StackPreempt,则相当于调用runtime.Gosched。
所以,到目前为止Go的抢占式调度还是很初级的,比如一个goroutine运行了很久,但是它并没有调用另一个函数,则它不会被抢占。当然,一个运行很久却不调用函数的代码并不是多数情况。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Single Page Web Applications
Michael Mikowski、Josh Powell / Manning Publications / 2013-9-30 / USD 44.99
Code for most web sites mostly runs on the server. When a user clicks on a link, the site reacts slowly because the browser sends information to the server and the server sends it back again before di......一起来看看 《Single Page Web Applications》 这本书的介绍吧!
RGB转16进制工具
RGB HEX 互转工具
RGB HSV 转换
RGB HSV 互转工具