Go 语言中 Goroutine 未执行的常见原因与正确同步方法-Golang

go 程序中启动的 goroutine 未输出预期结果,往往并非代码错误,而是因主 goroutine 过早退出导致整个程序终止——本文详解其原理、复现场景及三种专业级同步方案(waitgroup、channel、time.sleep 的适用边界)。

在 Go 中,go say(“world”) 启动了一个新的 goroutine,但程序的生命周期由 main goroutine 决定:一旦 main() 函数执行完毕并返回,整个进程立即退出,所有尚未完成的 goroutine(包括正在运行或排队中的)都会被强制终止。这正是原始示例中只看到 “hello” 输出而完全缺失 “world” 的根本原因:

func main() {
    go say("world") // 新 goroutine 已启动,但无任何等待机制
    say("hello")    // main goroutine 执行完这行后立即退出 → 程序终结!
}

尽管 goroutine 已调度,但 say(“hello”) 的 5 次打印极快完成,main() 函数随即结束,操作系统回收进程资源,say(“world”) 甚至可能还未被调度执行,更遑论完成全部循环。

✅ 正确做法:显式同步,确保主 goroutine 等待子任务完成

方案一:使用 sync.WaitGroup(推荐,最常用且语义清晰)

WaitGroup 是专为“等待一组 goroutine 完成”设计的标准工具,适用于已知并发数量的协作场景:

package main

import (
    "fmt"
    "sync"
)

func say(s string) {
    for i := 0; i < 5; i++ {
        fmt.Println(s)
    }
}

func main() {
    var wg sync.WaitGroup

    // 增加计数器:1 表示等待 say("world")
    wg.Add(1)
    go func() {
        defer wg.Done() // 确保完成时计数器减 1
        say("world")
    }()

    // 主 goroutine 同步执行 say("hello")
    say("hello")

    // 阻塞等待所有 goroutine 完成
    wg.Wait()
}

⚠️ 注意:wg.Done() 必须在 goroutine 内部调用(通常用 defer 保证),且 wg.Add() 必须在 go 语句前执行,否则存在竞态风险。

方案二:使用 Channel(适合需要传递结果或复杂协调的场景)

Channel 更适合需要数据通信、条件等待或动态 goroutine 生命周期管理的场景。以下为简化版双 goroutine 协同示例:

夏夕资源网专注于CMS网站模板,主流语言整站网站源码下载,网站建设相关教程分享,好用的软件素材整合下载,提供一站式便捷自助服务。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"zy.lucklyus.top",如遇到无法解压的请联系管理员!
夏夕资源网-网站模板_免费源码_资源素材 » Go 语言中 Goroutine 未执行的常见原因与正确同步方法-Golang
在线时间:12:00 - 22:00
关注微信公众号:微信公众号
站长邮箱:[email protected]
  • 运营天数: 1393+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4024021+
  • 本周更新: 0+
  • 最后更新: 2026-03-16

本站指数

×
  • 运营天数: 1393+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4024021+
  • 本周更新: 0+
  • 最后更新: 2026-03-16