Go优先调度
你的程序可能出现一个 goroutine 在运行时阻止了其他 goroutine 的运行,比如程序中有一个不让调度器运行的 for 循环:
func main() {
done := false
go func() {
done = true
}()
for !done {
}
println("done !")
}
for 的循环体不必为空,但如果代码不会触发调度器执行,将出现问题。
调度器会在 GC、Go 声明、阻塞 channel、阻塞系统调用和锁操作后再执行,也会在非内联函数调用时执行:
func main() {
done := false
go func() {
done = true
}()
for !done {
println("not done !") // 并不内联执行
}
println("done !")
}
可以添加 -m 参数来分析 for 代码块中调用的内联函数:
你也可以使用 runtime 包中的 Gosched() 来 手动启动调度器:
func main() {
done := false
go func() {
done = true
}()
for !done {
runtime.Gosched()
}
println("done !")
}
运行效果: