登录
首页 >  Golang >  Go教程

Go语言goroutine基础用法详解

时间:2026-05-22 18:30:14 210浏览 收藏

本文深入剖析Go语言中goroutine的正确使用方法,直击初学者高频踩坑点:循环变量共享导致输出异常(如全打印3)、盲目使用time.Sleep等待结果等典型错误,并系统讲解两种安全传参方案(显式传值和变量遮蔽)以及两种核心同步机制——sync.WaitGroup适用于简单完成通知,channel则胜任结果收集与流程协调,强调goroutine不是“加go就并发”,而是需与传参、同步、生命周期管理协同设计的工程实践。

Go语言如何使用goroutine_Golang并发基础用法详解

go 关键字启动 goroutine 很简单,但不加控制地乱用,轻则结果错乱,重则内存泄漏、程序卡死。它不是“加个 go 就并发了”,而是要配合同步机制、传参方式、生命周期管理一起用。

goroutine 启动时怎么传参才安全?别让循环变量被所有 goroutine 共享

最常见错误:在 for 循环里直接启 goroutine 并引用循环变量,比如:

for i := 0; i <p>原因:<code>i</code> 是同一个地址上的变量,所有匿名函数闭包都捕获了它的地址,等 goroutine 真正执行时,循环早已结束,<code>i == 3</code>。</p>
  • ✅ 正确做法一(推荐):把 i 当参数显式传进去
for i := 0; i 
  • ✅ 正确做法二:在循环内定义新变量绑定当前值
for i := 0; i <h3>怎么等 goroutine 执行完?别用 <code>time.Sleep</code>,它既不准也不可靠</h3><p><code>time.Sleep</code> 是调试玩具,生产环境必须换掉——CPU 忙时调度延迟大,可能还没执行完就跳过了;空闲时又白白多等。</p>
  • ✅ 场景一:只关心“是否完成”,不关心返回值 → 用 sync.WaitGroup
var wg sync.WaitGroup
for i := 0; i 
  • ✅ 场景二:要拿结果、做聚合、或控制执行顺序 → 用 chan
c := make(chan int, 2)
go func() { c <h3>channel 收发数据时有哪些硬性规则?漏 <code>close</code> 或类型不匹配会卡死</h3><p>无缓冲 channel 默认是同步的:发送方会阻塞,直到有接收方准备好;反过来也一样。这是它能做同步的底层原理。</p>
  • ⚠️ 常见卡死:用 for range ch 读 channel,但没人关它 → 永远等下一个值
  • ✅ 解法:发送方全部完成后,调用 close(ch),接收方 range 自动退出
  • ⚠️ 类型必须严格一致:chan int 不能当 chan interface{} 用,也不能和 混传
  • ✅ 缓冲 channel(如 make(chan int, 10))可缓解阻塞,但不解决逻辑同步问题——它只是“多存几个”,不是“不用等”

goroutine 泄漏怎么发现和避免?没回收的 goroutine 会一直占内存

goroutine 不会自动销毁,只要还在运行(比如卡在 channel 接收、死循环、没收到 context 取消信号),它就一直活着。跑着跑着几百上千个 goroutine 堆积,内存就爆了。

  • ✅ 必做:所有长期运行的 goroutine 都要监听 context.ContextDone() 通道
  • ✅ 必做:用 sync.WaitGroup 或 channel 明确标记“任务已结束”,尤其在循环启多个时
  • ⚠️ 危险模式:启 goroutine 去读一个可能永远不写入的 channel;或启了却忘了 defer wg.Done()
  • ? 快速检查:程序运行中访问 /debug/pprof/goroutine?debug=2(需导入 net/http/pprof)看 goroutine 数量是否异常增长

真正难的从来不是“怎么启 goroutine”,而是“怎么让它准时开始、正确协作、干净退出”。传参、同步、关闭、取消——这四个环节漏掉任何一个,都可能让并发变成并行灾难。

本篇关于《Go语言goroutine基础用法详解》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!

资料下载
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>