Go语言-->sync.WaitGroup 详细解释

sync.WaitGroup 详细解释

sync.WaitGroup 是 Go 语言中用于同步多个 goroutine 的完成的工具。它允许主 goroutine 等待所有子 goroutine 执行完毕后再继续。

核心概念

WaitGroup 内部维护一个计数器

  • Add(n): 计数器加 n(通常在启动 goroutine 前调用)
  • Done(): 计数器减 1(在 goroutine 完成时调用)
  • Wait(): 阻塞直到计数器变为 0

基本用法

go 复制代码
package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	var wg sync.WaitGroup

	// 添加 3 个 goroutine 到等待组
	wg.Add(3)

	// 启动第一个 goroutine
	go func() {
		defer wg.Done() // 完成时计数器 -1
		fmt.Println("任务 1 开始")
		time.Sleep(1 * time.Second)
		fmt.Println("任务 1 完成")
	}()

	// 启动第二个 goroutine
	go func() {
		defer wg.Done()
		fmt.Println("任务 2 开始")
		time.Sleep(2 * time.Second)
		fmt.Println("任务 2 完成")
	}()

	// 启动第三个 goroutine
	go func() {
		defer wg.Done()
		fmt.Println("任务 3 开始")
		time.Sleep(500 * time.Millisecond)
		fmt.Println("任务 3 完成")
	}()

	// 等待所有 goroutine 完成
	wg.Wait()
	fmt.Println("所有任务完成!")
}

输出

复制代码
任务 1 开始
任务 2 开始
任务 3 开始
任务 3 完成
任务 1 完成
任务 2 完成
所有任务完成!

关键特性

方法 说明
Add(n) 计数器加 n,必须在启动 goroutine 前调用
Done() 计数器减 1,通常用 defer 确保执行
Wait() 阻塞直到计数器为 0

常见模式

1. 批量处理任务

go 复制代码
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
	wg.Add(1)
	go func(id int) {
		defer wg.Done()
		// 处理任务
		fmt.Printf("处理任务 %d\n", id)
	}(i)
}
wg.Wait()

注意事项

⚠️ 常见错误

  • Add() 调用晚于 goroutine 启动
  • 忘记调用 Done()
  • Wait() 前计数器已为 0

最佳实践

  • 使用 defer wg.Done() 确保执行
  • 在启动 goroutine 前调用 Add()
  • 避免在 goroutine 中调用 Add()
相关推荐
星期八不上发条几秒前
智能指针是什么?使用场景,循环引用解决办法,面试回答
开发语言·c++·stl
OKkankan9 分钟前
Python 基础进阶(三):从函数、类到 asyncio 与 FastAPI 后端开发实战
开发语言·python
泡海椒1 小时前
jquick-pdf 防止 PDF 内容分页断裂:keepTogether 属性妙用
java·开发语言·pdf
知识的搬运工旺仔1 小时前
CREATE INDEX CONCURRENTLY:线上建索引不阻塞 DML 的代价与坑
数据库·后端·sql
小蒜学长1 小时前
大学生健康饮食的智慧管理系统(代码+数据库+LW)
java·后端·springboot·大学生·健康饮食
小蒜学长2 小时前
基于Java的论坛数据可视化分析系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·数据可视化·论坛系统
青山木2 小时前
RocketMQ 入门到原理(一):整体架构与消息的生命周期
java·分布式·后端·中间件·架构·rocketmq
黑马程序员毕设2 小时前
基于微信小程序的二手交易平台设计与实现报告
前端·人工智能·spring boot·后端·考研
传奇开心果编程2 小时前
【Rust入门练中学】 第1课:从零开始
开发语言·学习·rust