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 完全处理完毕:

PaperAiBye
PaperAiBye

支持近30多种语言降ai降重,并且支持多种语言免费测句子的ai率,支持英文aigc报告等

下载
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

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

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

4

2026.01.16

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

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

1

2026.01.16

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

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

10

2026.01.16

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

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

33

2026.01.15

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

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

15

2026.01.15

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

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

42

2026.01.15

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

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

7

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号