You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言中如何用Mutex配合Goroutine实现锁定与等待?

解决方案:使用sync.WaitGroup实现并发任务启动与等待

你的核心需求是让DoSomething()可以并发调用且立即返回,同时Wait()能确保所有通过DoSomething()启动的goroutine执行完成,避免panic或sys.Exit()导致任务中断。原有的互斥锁方案无法兼顾这两点,推荐使用sync.WaitGroup来实现:

基础实现代码

import "sync"

var wg sync.WaitGroup

func DoSomething() {
    // 在启动goroutine前增加任务计数,确保Wait()能感知到该任务
    wg.Add(1)
    go func() {
        // 确保无论业务代码是否panic,都会标记任务完成
        defer wg.Done()
        // 业务代码
    }()
}

func Wait() {
    // 阻塞直到所有任务计数被抵消(所有goroutine执行完毕)
    wg.Wait()
}

带临界区保护的实现(如果业务代码需要访问共享资源)

如果你的业务代码需要互斥访问共享资源,只需在goroutine内部添加互斥锁即可,不影响并发启动和等待逻辑:

import "sync"

var (
    wg   sync.WaitGroup
    lock sync.Mutex
)

func DoSomething() {
    wg.Add(1)
    go func() {
        defer wg.Done()
        
        lock.Lock()
        defer lock.Unlock()
        // 业务代码(安全访问共享资源)
    }()
}

func Wait() {
    wg.Wait()
}

为什么原有方案不可行

  • 第一种方案(锁在goroutine外):DoSomething()调用时先获取锁,而锁被goroutine持有直到任务完成,导致后续DoSomething()调用必须等待前一个goroutine释放锁,完全丧失并发能力;
  • 第二种方案(锁在goroutine内):Wait()中的锁操作可能在goroutine还未启动(未获取锁)时就执行完毕,无法保证等待所有任务完成。

内容的提问来源于stack exchange,提问作者Dan Jones

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 08:08:18