
Go程序主函数退出后会立即终止所有goroutine,导致未完成的并发任务(如fmt.Println)被静默丢弃;必须通过同步机制(如sync.WaitGroup)等待goroutine完成。
go程序主函数退出后会立即终止所有goroutine,导致未完成的并发任务(如`fmt.println`)被静默丢弃;必须通过同步机制(如`sync.waitgroup`)等待goroutine完成。
在Go中,启动一个goroutine(如 go func() {...}())是非阻塞且异步的:它将任务提交到Go运行时调度器后,主goroutine(即main函数)会继续执行后续代码,并在返回时直接退出整个程序——此时所有尚未执行完毕的子goroutine会被强制终止,其内部的I/O操作(包括fmt.Println)根本来不及触发。
你提供的代码正是典型场景:
package main
import "fmt"
func main() {
for i := 0; i <p>该循环虽启动了20个goroutine,但<code>main</code>函数几乎瞬间执行完毕,没有为它们预留任何运行时间,因此<strong>控制台无任何输出</strong>。</p><p>✅ 正确做法是引入同步原语确保主goroutine等待所有工作完成。最常用、最推荐的方式是 <code>sync.WaitGroup</code>:</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 (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
for i := 0; i <p>? 关键要点:</p>
-
wg.Add(1)必须在go语句之前调用,避免竞态(因Add和Done需严格配对); - 使用
defer wg.Done()是惯用写法,确保即使goroutine内发生panic也能正确减计数; - 不要依赖
time.Sleep替代同步——它不可靠、不精确,且掩盖了并发控制的本质问题; - 若需传递循环变量,请像示例中一样通过参数
j int显式捕获当前值,避免闭包引用同一变量i导致全部打印相同结果(本例已正确处理)。
掌握 WaitGroup 是编写健壮Go并发程序的第一课:它让“启动并发”与“等待完成”解耦,既保持简洁性,又保证确定性行为。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










