【问题标题】:Loop in goroutine hangs programgoroutine中的循环挂起程序
【发布时间】:2025-12-12 13:00:02
【问题描述】:

为什么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 会导致“进程耗时太长”?

【问题讨论】:

    标签: go


    【解决方案1】:

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

    参考:

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

    由于主线程也是一个goroutine,它不获取上下文切换,永远休眠。

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

    更多有用的参考资料:

    【讨论】: