循环在goroutine挂起程序

时间:2017-03-17 08:18:46

标签: go

为什么在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会导致“过程花费太长时间”?

1 个答案:

答案 0 :(得分:8)

这是因为goroutine是合作(不是完全抢占)任务,而上下文切换只发生在有一些IO,系统调用,time.Sleep()或调用大型函数时才需要扩展堆栈。

参考:

你的atomic.AddUint64(&ops, 1)是一个小函数,不需要扩展堆栈。所以上下文切换永远不会发生。

由于主线程也是goroutine,它不会获取上下文切换,并且会永远睡眠。

an open issue使golang在紧密循环中抢占先机,但尚未解决。

更有用的参考资料: