全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

如何在Golang中使用sync处理并发操作_使用Mutex和WaitGroup同步

Go中sync包提供Mutex保障共享数据读写安全、WaitGroup协调goroutine生命周期;Mutex需作为结构体字段配defer解锁,WaitGroup须先Add后启动goroutine并defer Done。

在 Go 中处理并发时,sync 包是核心工具之一。它不靠语言层面的锁机制,而是提供轻量、明确、可组合的同步原语。其中 Mutex 用于保护共享数据不被多个 goroutine 同时修改,WaitGroup 用于等待一组 goroutine 完成。两者常配合使用,但职责分明:一个管“读写安全”,一个管“生命周期协调”。

用 Mutex 保护共享变量,避免竞态

sync.Mutex 是互斥锁,确保同一时刻只有一个 goroutine 能进入临界区。关键点是:锁必须作用于要保护的数据上,且加锁/解锁需成对出现(推荐用 defer mu.Unlock() 防止遗漏)。

常见错误是把锁定义在函数内(每次调用都是新锁),或忘记解锁导致死锁。正确做法是把 Mutex 作为结构体字段,与被保护数据放在一起:

type Counter struct {
    mu    sync.Mutex
    value int
}

func (c *Counter) Inc() {
    c.mu.Lock()
    defer c.mu.Unlock()
    c.value++
}

func (c *Counter) Value() int {
    c.mu.Lock()
    defer c.mu.Unlock()
    return c.value
}

用 WaitGroup 等待多个 goroutine 结束

sync.WaitGroup 不是用来保护数据的,而是用来“计数 + 阻塞等待”。它有三个方法:Add(n) 增加计数,Done() 减一(通常 defer 调用),Wait() 阻塞直到计数归零。

注意:Add 必须在启动 goroutine 之前调用,否则可能 Wait 已返回而 goroutine 还没开始;Done 必须和 Add 匹配,否则会 panic 或永远阻塞。

典型用法:

var wg sync.WaitGroup
for i := 0; i < 5; i++ {
    wg.Add(1)
    go func(id int) {
        defer wg.Done()
        fmt.Printf("goroutine %d done\n", id)
    }(i)
}
wg.Wait() // 主协程在此等待全部完成
fmt.Println("all done")

Mutex 和 WaitGroup 组合使用的典型场景

当多个 goroutine 并发更新共享状态,并需要等它们全部完成后再读取结果时,就该一起用:

  • 初始化一个 WaitGroup 和带 Mutex 的结果容器(如 map 或 struct)
  • 每个 goroutine 执行任务后,用 Mutex 安全地更新结果,再调用 Done()
  • 主 goroutine 调用 Wait() 后,再用 Mutex 安全读取最终结果

例如批量请求 API 并汇总响应码:

type Result struct {
    mu     sync.Mutex
    codes  map[int]int
}

func (r *Result) Add(code int) {
    r.mu.Lock()
    defer r.mu.Unlock()
    r.codes[code]++
}

// ... 启动多个 goroutine 调用 r.Add(statusCode),最后 wg.Wait()

替代方案与注意事项

不是所有并发都需要 Mutex。优先考虑无锁方式:

  • channel 传递数据而非共享内存(Go 的哲学)
  • 对简单计数,可用 sync/atomic(如 atomic.AddInt64
  • RWMutex 适合读多写少场景,允许多个读、单个写

WaitGroup 不能重复使用(重置需用 sync.Pool 或新建),也不支持超时——如需等待带超时,应改用 context.WithTimeout + select


# go  # golang  # 工具  # ai  # 无锁  # select  # 结构体  # Struct  # map  # 并发  # channel  # 多个  # 解锁  # 死锁  # 都是  # 也不  # 还没  # 在此  # 只有一个  # 再用  # 不被 


相关文章: 上海网站制作网页,上海本地的生活网站有哪些?最好包括生活的各个方面的?  如何在建站主机中优化服务器配置?  如何通过cPanel快速搭建网站?  建站主机是否等同于虚拟主机?  可靠的网站设计制作软件,做网站设计需要什么样的电脑配置?  如何在Golang中使用replace替换模块_指定本地或远程路径  百度网页制作网站有哪些,谁能告诉我百度网站是怎么联系?  头像制作网站在线制作软件,dw网页背景图像怎么设置?  如何通过VPS建站实现广告与增值服务盈利?  怀化网站制作公司,怀化新生儿上户网上办理流程?  如何在阿里云香港服务器快速搭建网站?  免费视频制作网站,更新又快又好的免费电影网站?  设计网站制作公司有哪些,制作网页教程?  建站之星上传入口如何快速找到?  制作网站的过程怎么写,用凡科建站如何制作自己的网站?  网站制作需要会哪些技术,建立一个网站要花费多少?  浅谈Javascript中的Label语句  C#怎么使用委托和事件 C# delegate与event编程方法  如何通过万网虚拟主机快速搭建网站?  建站之星云端配置指南:模板选择与SEO优化一键生成  如何快速搭建高效简练网站?  网站专业制作公司有哪些,做一个公司网站要多少钱?  网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?  h5在线制作网站电脑版下载,h5网页制作软件?  ,购物网站怎么盈利呢?  学校建站服务器如何选型才能满足性能需求?  如何选择高效可靠的多用户建站源码资源?  如何用狗爹虚拟主机快速搭建网站?  宠物网站制作html代码,有没有专门介绍宠物如何养的网站啊?  如何通过宝塔面板实现本地网站访问?  如何选择建站程序?包含哪些必备功能与类型?  哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?  php条件判断怎么写_ifelse和switchcase的使用区别【对比】  网页设计与网站制作内容,怎样注册网站?  香港服务器如何优化才能显著提升网站加载速度?  大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?  建站主机选哪种环境更利于SEO优化?  山东网站制作公司有哪些,山东大源集团官网?  建站与域名管理如何高效结合?  如何快速查询网站的真实建站时间?  为什么Go需要go mod文件_Go go mod文件作用说明  建站主机选购指南与交易推荐:核心配置解析  如何高效配置IIS服务器搭建网站?  音乐网站服务器如何优化API响应速度?  如何在阿里云购买域名并搭建网站?  如何快速配置高效服务器建站软件?  想学网站制作怎么学,建立一个网站要花费多少?  如何通过IIS搭建网站并配置访问权限?  导航网站建站方案与优化指南:一站式高效搭建技巧解析  C++用Dijkstra(迪杰斯特拉)算法求最短路径 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。