深入浅出Golang关键字"go" 2
三岁于辛 · · 956 次点击 · · 开始浏览前文"深入浅出Golang关键字"go""最后留了几个问题:
func main() {
runtime.GOMAXPROCS(1)
for i := 0; i < 10; i++ {
go println(i)
}
runtime.Gosched()
time.Sleep(time.Second)
}
runtime.Gosched()
这一行代码。
如果注释掉结果会怎样??
如果把这一行换成 runtime.Goexit() 或者 os.Exit(0) 又会是如何呢??
如果有关注到这个问题并且自己尝试过的朋友会发现:
- 如果把 runtime.Gosched() 注释掉,结果会是 0~9;
- 如果换成 runtime.Goexit(),结果会是先输出 0~9,然后程序 panic;
- 如果是 os.Exit(0),则什么也不会输出。
对于 0~9 的结果,很多人会奇怪,runtime.Gosched() 到底怎样影响到结果的?而 runtime.Goexit() 与 runtime.Gosched() 之间又存在怎样的区别呢?
runtime.Gosched() 主要做了一件事就是尝试交出 P 操作权限,等待其它 gorotine 执行完成后再继续执行当前 gorotine,结合前文的 next 位置,则输出了 9 0~8 这样的结果。
但是当把这一行注释了,程序会卡在 time.Sleep 处,这时候 go 程序设计中的另一个东西出场了——sys monitor 线程,这是 go 语言设计中的唯一一个(主线程除外)独立的线程。它的作用是监控 gorotine 状态的。当主 goroutine 在 sleep 时,monitor 认为占用时间不符合预期,它会把 P 让出来,而自己则进入 P 的 gorotine 队列等待。那么问题来了,P 有 next 位置呀,所以这时候 main gorotine 就占了 next 位置。从而导致输出顺序变成 0~9了。
Goexit() 与 Gosched() 唯一不同的地方则是它会丢弃此行代码后的所有堆栈,
并且如果丢弃的是 main gorotine 的话会 panic。结果也自然是输出 0~9 然后 panic 了。
os.Exit() 自不必多说了。
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
收入到我管理的专栏 新建专栏
前文"深入浅出Golang关键字"go""最后留了几个问题:
func main() {
runtime.GOMAXPROCS(1)
for i := 0; i < 10; i++ {
go println(i)
}
runtime.Gosched()
time.Sleep(time.Second)
}
runtime.Gosched()
这一行代码。
如果注释掉结果会怎样??
如果把这一行换成 runtime.Goexit() 或者 os.Exit(0) 又会是如何呢??
如果有关注到这个问题并且自己尝试过的朋友会发现:
- 如果把 runtime.Gosched() 注释掉,结果会是 0~9;
- 如果换成 runtime.Goexit(),结果会是先输出 0~9,然后程序 panic;
- 如果是 os.Exit(0),则什么也不会输出。
对于 0~9 的结果,很多人会奇怪,runtime.Gosched() 到底怎样影响到结果的?而 runtime.Goexit() 与 runtime.Gosched() 之间又存在怎样的区别呢?
runtime.Gosched() 主要做了一件事就是尝试交出 P 操作权限,等待其它 gorotine 执行完成后再继续执行当前 gorotine,结合前文的 next 位置,则输出了 9 0~8 这样的结果。
但是当把这一行注释了,程序会卡在 time.Sleep 处,这时候 go 程序设计中的另一个东西出场了——sys monitor 线程,这是 go 语言设计中的唯一一个(主线程除外)独立的线程。它的作用是监控 gorotine 状态的。当主 goroutine 在 sleep 时,monitor 认为占用时间不符合预期,它会把 P 让出来,而自己则进入 P 的 gorotine 队列等待。那么问题来了,P 有 next 位置呀,所以这时候 main gorotine 就占了 next 位置。从而导致输出顺序变成 0~9了。
Goexit() 与 Gosched() 唯一不同的地方则是它会丢弃此行代码后的所有堆栈,
并且如果丢弃的是 main gorotine 的话会 panic。结果也自然是输出 0~9 然后 panic 了。
os.Exit() 自不必多说了。