为什么在time.Sleep(time.Nanosecond)
被注释掉时,以下程序会挂起?
package main
import "fmt"
import "time"
import "sync/atomic"
func main() {
var ops uint64 = 0
for i := 0; i < 50; i++ {
go func() {
for {
atomic.AddUint64(&ops, 1)
time.Sleep(time.Nanosecond)
}
}()
}
time.Sleep(time.Millisecond)
opsFinal := atomic.LoadUint64(&ops)
fmt.Println("ops:", opsFinal)
}
第二个问题,为什么running this program in the sandbox会导致“过程花费太长时间”?
答案 0 :(得分:8)
这是因为goroutine是合作(不是完全抢占)任务,而上下文切换只发生在有一些IO,系统调用,time.Sleep()
或调用大型函数时才需要扩展堆栈。
参考:
你的atomic.AddUint64(&ops, 1)
是一个小函数,不需要扩展堆栈。所以上下文切换永远不会发生。
由于主线程也是goroutine,它不会获取上下文切换,并且会永远睡眠。
有an open issue使golang在紧密循环中抢占先机,但尚未解决。
更有用的参考资料: