我们提供安全,免费的手游软件下载!

安卓手机游戏下载_安卓手机软件下载_安卓手机应用免费下载-先锋下载

当前位置: 主页 > 软件教程 > 软件教程

Go Runtime调度器:抢占逻辑源码解析

来源:网络 更新时间:2024-09-16 09:31:34

在前文《Go runtime调度器精讲(七):案例分析》中,我们介绍了一个抢占的案例。本文将继续深入源码层面,探讨Go runtime调度器是如何实现抢占逻辑的。

sysmon线程

在之前的文章中我们提到了sysmon线程,它是运行在系统栈上的监控线程,负责监控goroutine的状态并做相应处理。本文将重点介绍sysmon线程的抢占处理。

sysmon 的创建在 src/runtime/proc.go:sysmon 中:

// The main goroutine.
func main() {
	...
	if GOARCH != "wasm" { // no threads on wasm yet, so no sysmon
		systemstack(func() {
			newm(sysmon, nil, -1)
		})
	}
    ...
}

sysmon 不需要和P绑定,作为监控线程运行在系统栈。进入 sysmon 后,根据goroutine的状态进行相应处理,包括抢占处理。

抢占运行时间过长的goroutine

当sysmon线程发现运行时间过长的goroutine时,会将goroutine的 stackguard0 更新为一个比任何栈都大的 stackPreempt 值。当线程进行函数调用时,会比较栈顶 rsp g.stackguard0 ,检查goroutine栈的栈空间。因为更新了goroutine栈的 stackguard0 ,线程会走到扩展逻辑,进入根据 preempt 标志位,执行对应的抢占调度。

小结

本文介绍了sysmon线程和抢占运行时间过长的goroutine的实现方式。下一篇文章将继续深入介绍sysmon线程和抢占系统调用时间过长的goroutine。