go 异步抢占调度
Contents
go 的异步抢占调度
go 1.13
在go 1.13 (包括1.13)之前,并不是真正意思上的抢占。什么是真正的抢占式调度,为了探究这个问题,网上广为流传这么一段代码
package main
import "fmt"
func main() {
go func(i int) {
for {
i++
fmt.Println(i)
}
}(0)
for {
}
}在go 1.13中这段代码的表象是,程序会持续输出,过不了多久便停止了输出,但是程序并没有终止,通过top命令查看会发现程序的cpu负载很高,这是因为for{}导致,负责打印的goroutine应该是在某处"卡住"了。
调试
本地高于go 1.13,可以用GODEBUG=asyncpreemptoff=1 go run main.go来调试。也可以在docker里面跑一个go 1.13的版本
docker 里面调试
-
$ docker pull golang:1.13 -
$ docker run -it golang:1.13 -
在容器里面,安装vim
root@a2ea6ba48cc9:/go# apt-get update root@a2ea6ba48cc9:/go# apt-get install vim -
还需要一个
dlv的golang调试工具go env -w GO111MODULE=on go env -w GOPROXY=https://goproxy.cn,direct go get github.com/go-delve/delve/cmd/dlv@latest -
在容器里面复制上面代码
root@a2ea6ba48cc9:/go/src# vim main.go -
运行
root@a2ea6ba48cc9:/go/src# go run main.go