You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang协程执行结果不符预期,如何调整代码实现预期输出?

如何让Go协程按预期顺序执行

现有代码的问题分析

  1. 主goroutine启动jobX协程后,会立刻执行jobY。Go的M:N调度器在没有阻塞操作的情况下,不会主动切换到新启动的协程,导致jobY会被完整执行完,才会轮到jobX运行。
  2. wg.Wait()被放在fmt.Println("end")之后,导致"end"会在jobX执行完成前就被打印出来。

修改方案

  1. 在启动jobX协程后,调用runtime.Gosched()主动让出CPU时间片,让调度器优先执行jobX协程。
  2. 将wg.Wait()移到fmt.Println("end")之前,确保"end"在所有协程执行完毕后才打印。

修改后的完整代码

import (
    "fmt"
    "runtime"
    "sync"
    "time"
)

func jobX(wg *sync.WaitGroup) {
    defer wg.Done()
    for i := 0; i < 5; i++ {
        fmt.Println("routine X: ", i)
        if i == 2 {
            time.Sleep(3 * time.Second)
        }
    }
}

func jobY() {
    for i := 0; i < 5; i++ {
        fmt.Println("routine Y: ", i)
    }
}

func main() {
    var wg sync.WaitGroup

    fmt.Println("starting go routine...")

    wg.Add(1)
    go jobX(&wg)
    // 主动让出时间片,让jobX协程先执行
    runtime.Gosched()
    jobY()

    // 等待jobX完成后再打印end
    wg.Wait()
    fmt.Println("end")
}

执行流程说明

  • 主goroutine启动jobX后,调用runtime.Gosched()交出CPU,调度器切换到jobX执行,依次打印routine X: 0、routine X: 1、routine X: 2,随后进入3秒睡眠。
  • jobX睡眠时,主goroutine被调度继续执行,完整跑完jobY并打印所有routine Y的输出。
  • jobY执行完毕后,主goroutine通过wg.Wait()等待jobX结束。
  • jobX睡眠结束后,继续打印routine X: 3、routine X: 4,执行wg.Done()解除等待。
  • 最后主goroutine打印"end",完全符合预期输出。

内容的提问来源于stack exchange,提问作者Mirana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 03:37:18