go程序启动goroutine后若不等待其完成,main函数会立即结束,导致所有goroutine被强制终止,文件写入失败——这是初学者常见的并发陷阱。
go程序启动goroutine后若不等待其完成,main函数会立即结束,导致所有goroutine被强制终止,文件写入失败——这是初学者常见的并发陷阱。
在Go中,go关键字用于启动一个新的goroutine,它在后台异步执行,但不会阻塞主线程。这意味着:当main()函数执行完for循环后立即返回,整个程序随之退出,而此时由go writeOutput()启动的5个goroutine很可能尚未开始执行,或仅执行到一半(如已创建文件但未写入内容),就被系统强制终止。
你原始代码的问题核心在于缺少同步机制:
func main() {
for i := 0; i <p>✅ 正确做法是使用 sync.WaitGroup 显式等待所有goroutine完成:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2525" title="Go语言(Golang)1.26.0"><img
src="https://img.php.cn/upload/manual/001/589/237/6a6adeed24a4a355.png" alt="Go语言(Golang)1.26.0" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2525" title="Go语言(Golang)1.26.0" class="overflowclass">Go语言(Golang)1.26.0</a>
<p class="overflowclass">Go语言(Golang)1.26.0版本官方下载,版本号 1.26.0,适合旧项目维护、兼容性测试和指定版本开发环境搭建。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2525" title="Go语言(Golang)1.26.0" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div><pre class="brush:php;toolbar:false;">package main
import (
"math/rand"
"os"
"strconv"
"sync"
)
func main() {
var wg sync.WaitGroup
for i := 0; i <p>⚠️ 注意事项:</p>
- 闭包变量捕获问题:若在循环中直接传入i(如go func(i int){...}(i)),需显式传参;本例未使用循环变量,故无此风险。
- 随机数种子:rand.Intn默认使用相同种子,多次运行可能生成重复文件名(导致覆盖)。建议在main()开头添加 rand.Seed(time.Now().UnixNano())(需导入time)。
- 资源与错误安全:生产代码中务必检查os.Create和WriteString的返回错误,避免静默失败。
- 替代方案:除WaitGroup外,也可用channel接收完成信号,但对简单并行任务,WaitGroup更直观简洁。
总结:Go的并发模型强调“明确同步”——goroutine不是“后台守护线程”,而是受主程序生命周期严格约束的轻量级协程。理解main退出即程序终结这一原则,是掌握Go并发的第一课。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










