知识卡片

抢占保证机会

普通读书笔记卡 · 1481.b

内容

(书中 Go 1.14)长时间运行或处于系统调用的协程会被系统监控(每 10ms 检测一次)标记并抢占;Go 1.14 之前只能在函数调用的序言阶段检查抢占标记,密集循环无函数调用则无法被抢占,Go 1.14 后引入操作系统信号(_SIGURG)实现异步抢占,能打断紧密循环。抢占让”合作式让出”升级为更公平的运行时保障,具体信号选择与抢占时机是该版本的实现细节。

参考来源

- 位置:《Go语言底层原理剖析》第15章《深入协程设计与调度原理》15.6.3、15.6.4节《抢占调度》《执行时间过长的抢占调度》 - 结论依据:原文明确"系统监控每隔10ms会检测是否有准备就绪的网络协程……系统监控服务会判断当前协程是否运行时间过长,或者处于系统调用阶段,如果是,则会抢占当前G的执行",并说明"在Go 1.14之前……调度发生的时机主要在执行函数调用阶段","为了解决这一问题,Go 1.14之后引入了信号强制抢占的机制",借助 \_SIGURG 信号打断执行,因此可以推出"抢占机制随 Go 1.14 从仅能在函数调用点检查升级为可异步打断紧密循环"的结论。 - 原始内容:系统监控每隔10ms会检测是否有准备就绪的网络协程,并放置到全局队列中。和抢占调度相关的是,系统监控服务会判断当前协程是否运行时间过长,或者处于系统调用阶段,如果是,则会抢占当前G的执行……在Go1.14中,如果当前协程的执行时间超过了10ms,则需要执行抢占……这种抢占的方式面临着一定的问题,当执行过程中没有函数调用……协程将没有被抢占的机会。为了解决这一问题,Go 1.14之后引入了信号强制抢占的机制。