Golang使用WaitGroup控制子任务完成

WaitGroup用于等待一组goroutine完成,通过Add、Done、Wait方法实现同步。典型用法是在主协程中Add增加计数,每个子协程完成后调用Done,最后主协程Wait阻塞直至所有任务结束。常见于并发请求或批量处理场景,需注意Add在goroutine外调用、避免复制WaitGroup、配合defer确保Done执行。可与Context结合实现超时控制,是Go并发编程中可靠且高效的同步工具。

golang使用waitgroup控制子任务完成

在Go语言中,WaitGroup 是

sync

包提供的同步原语,用于等待一组并发的goroutine执行完成。它特别适合主协程需要等待多个子任务结束后再继续的场景。使用 WaitGroup 可以避免程序提前退出或资源未释放的问题。

WaitGroup 基本用法

WaitGroup 提供三个核心方法:

Add(n):增加计数器,表示要等待的goroutine数量。 Done():在goroutine中调用,表示当前任务完成,计数器减1。 Wait():阻塞主协程,直到计数器归零。

典型结构如下:

var wg sync.WaitGroupfor i := 0; i < 5; i++ {    wg.Add(1)    go func(id int) {        defer wg.Done()        // 执行任务        fmt.Printf("任务 %d 完成n", id)    }(i)}wg.Wait() // 等待所有任务完成fmt.Println("所有子任务已完成")

常见使用模式

实际开发中,常结合 for 循环启动多个goroutine,并确保每个都正确调用 Done()。推荐使用 defer wg.Done() 防止因 panic 或提前返回导致计数器不一致。

立即学习“go语言免费学习笔记(深入)”;

示例:并发抓取多个URL

package mainimport (    "fmt"    "net/http"    "sync")func fetch(url string, wg *sync.WaitGroup) {    defer wg.Done()    resp, err := http.Get(url)    if err != nil {        fmt.Printf("请求失败 %s: %vn", url, err)        return    }    defer resp.Body.Close()    fmt.Printf("成功获取 %s,状态码: %dn", url, resp.StatusCode)}func main() {    urls := []string{        "https://httpbin.org/get",        "https://httpbin.org/delay/2",        "https://httpbin.org/status/200",    }    var wg sync.WaitGroup    for _, url := range urls {        wg.Add(1)        go fetch(url, &wg)    }    wg.Wait()    fmt.Println("所有HTTP请求完成")}

注意事项

不要复制WaitGroup:传递时应使用指针,否则会引发竞态或panic。 Add的调用应在goroutine外:如果在goroutine内部Add,可能主协程还没注册完就进入Wait,导致漏等。 计数不能为负:Done调用次数不能超过Add设定值,否则panic。

错误示例(避免):

go func() {    wg.Add(1) // 错误:Add在goroutine内    defer wg.Done()}()

与Context结合使用

在更复杂的场景中,可将 WaitGroup 与 context.Context 结合,实现超时控制或取消机制。WaitGroup负责等待完成,Context负责中断信号。

例如,设置整体超时:

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)defer cancel()// 启动任务...wg.Wait() // 仍需等待,但受上下文约束

基本上就这些。WaitGroup简单高效,是Go中控制并发任务生命周期的常用工具。只要注意Add时机和资源安全,就能可靠使用。

以上就是Golang使用WaitGroup控制子任务完成的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1405002.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
Golang使用Goquery进行网页解析与抓取
上一篇 2025年12月15日 20:58:53
Golang错误信息结构化管理方法
下一篇 2025年12月15日 20:59:04

相关推荐

发表回复

登录后才能评论
关注微信