0

0

Go 中 Goroutine 未执行的常见原因:主函数提前退出

聖光之護

聖光之護

发布时间:2026-01-17 12:45:26

|

392人浏览过

|

来源于php中文网

原创

Go 中 Goroutine 未执行的常见原因:主函数提前退出

go 程序在 `main` 函数返回时立即终止,不会等待其他 goroutine 完成;添加 `time.sleep` 反而可能加剧竞态,导致子 goroutine 来不及执行打印逻辑即被强制结束。

在 Go 中,程序生命周期完全由 main 函数控制:一旦 main 函数执行完毕(无论是否显式 return),整个进程立即退出,所有正在运行的非主 goroutine(包括已启动但尚未调度或正在执行的)都会被强制终止,且不触发任何清理逻辑。

你观察到的现象——加了 time.Sleep(time.Second) 后 my_func 似乎“不执行”——并非因为 goroutine 被阻塞或未启动,而是典型的竞态 + 主函数过早退出问题:

  • ✅ go my_func(c) 成功启动 goroutine;
  • ✅ c
  • ❌ 但 my_func 中的 fmt.Println(

⚠️ 注意:time.Sleep 在此处不仅无益,反而有害——它延迟了 c

正确做法:使用通道同步(推荐)

通过额外的 done 通道确保 main 等待子 goroutine 完全处理完毕:

来福FM
来福FM

来福 - 你的私人AI电台

下载
package main

import (
    "fmt"
    "time"
)

func my_func(c, done chan int) {
    val := <-c
    fmt.Println(val)
    done <- 1 // 通知 main:已完成
}

func main() {
    c := make(chan int)
    done := make(chan int)
    go my_func(c, done)

    time.Sleep(time.Second) // 仅为模拟延迟,实际应避免随意 Sleep
    c <- 3
    <-done // 阻塞等待 my_func 完成打印
}

✅ 输出确定为 3,且程序正常退出。

更健壮的替代方案:sync.WaitGroup

当需等待多个 goroutine 时,sync.WaitGroup 更清晰、更符合工程实践:

package main

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

func my_func(c chan int, wg *sync.WaitGroup) {
    defer wg.Done()
    fmt.Println(<-c)
}

func main() {
    c := make(chan int)
    var wg sync.WaitGroup
    wg.Add(1)
    go my_func(c, &wg)

    time.Sleep(time.Second)
    c <- 3
    wg.Wait() // 等待所有 goroutine 完成
}

关键原则总结

  • ? 永远不要依赖 time.Sleep 实现 goroutine 同步:它不可靠、难维护、掩盖真正问题;
  • 始终显式同步:用 channel(done 信号)、sync.WaitGroup 或 context 控制生命周期;
  • ? 理解 Go 内存模型中的 “happens-before” 关系:例如,“向 channel 发送” happens before “从同一 channel 接收完成”,这是唯一可依赖的顺序保证;
  • ? 调试提示:本地运行时若偶尔看到输出,是调度器偶然让 goroutine 抢占到时间片;但在 CI、容器或 Playground 中极易失败——这恰恰证明代码存在竞态,而非“有时能工作”。

遵循同步约定,你的并发 Go 代码才能真正可靠、可预测、可维护。

相关专题

更多
Golang channel原理
Golang channel原理

本专题整合了Golang channel通信相关介绍,阅读专题下面的文章了解更多详细内容。

246

2025.11.14

golang channel相关教程
golang channel相关教程

本专题整合了golang处理channel相关教程,阅读专题下面的文章了解更多详细内容。

342

2025.11.17

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

40

2026.01.16

全民K歌得高分教程大全
全民K歌得高分教程大全

本专题整合了全民K歌得高分技巧汇总,阅读专题下面的文章了解更多详细内容。

65

2026.01.16

C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

20

2026.01.16

java数据库连接教程大全
java数据库连接教程大全

本专题整合了java数据库连接相关教程,阅读专题下面的文章了解更多详细内容。

33

2026.01.15

Java音频处理教程汇总
Java音频处理教程汇总

本专题整合了java音频处理教程大全,阅读专题下面的文章了解更多详细内容。

16

2026.01.15

windows查看wifi密码教程大全
windows查看wifi密码教程大全

本专题整合了windows查看wifi密码教程大全,阅读专题下面的文章了解更多详细内容。

56

2026.01.15

浏览器缓存清理方法汇总
浏览器缓存清理方法汇总

本专题整合了浏览器缓存清理教程汇总,阅读专题下面的文章了解更多详细内容。

15

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 3.8万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号