最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語(yǔ)言使用WaitGroup等待多個(gè)協(xié)程完成

 更新時(shí)間:2026年02月25日 11:00:19   作者:程序員愛(ài)釣魚(yú)  
sync.WaitGroup是Go標(biāo)準(zhǔn)庫(kù)中的一個(gè)結(jié)構(gòu)體,用于等待一組goroutine執(zhí)行完成,本文就來(lái)介紹一下Go語(yǔ)言使用WaitGroup等待多個(gè)協(xié)程完成,感興趣的可以了解一下

在并發(fā)編程中,經(jīng)常需要在主協(xié)程中等待多個(gè)子協(xié)程執(zhí)行完畢再進(jìn)行下一步操作。Go 提供了一個(gè)非常實(shí)用的同步原語(yǔ):sync.WaitGroup,可以幫助我們優(yōu)雅地解決這個(gè)問(wèn)題。

一、什么是 WaitGroup?

sync.WaitGroup 是 Go 標(biāo)準(zhǔn)庫(kù)中的一個(gè)結(jié)構(gòu)體,用于等待一組 goroutine 執(zhí)行完成。

常用方法:

方法功能說(shuō)明
Add(n int)設(shè)置需要等待的 goroutine 數(shù)量
Done()每個(gè) goroutine 執(zhí)行完成后調(diào)用,計(jì)數(shù)器減 1
Wait()阻塞當(dāng)前 goroutine,直到計(jì)數(shù)器歸零為止

二、為什么需要 WaitGroup?

在并發(fā)場(chǎng)景中,如果主函數(shù)先于子協(xié)程執(zhí)行完畢,程序?qū)?huì)直接退出,導(dǎo)致協(xié)程未完成任務(wù)。例如:

func main() {
    go func() {
        fmt.Println("Hello from goroutine")
    }()
    // 沒(méi)有等待,主函數(shù)直接退出
}

輸出往往為空或者輸出不完整,根本原因是主 goroutine 沒(méi)有等待子 goroutine。

三、實(shí)戰(zhàn)案例:等待多個(gè)協(xié)程完成任務(wù)

示例:開(kāi)啟 5 個(gè) goroutine,每個(gè)打印一條消息,主程序等待所有協(xié)程完成后再退出。

package main

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

func worker(id int, wg *sync.WaitGroup) {
    defer wg.Done() // 執(zhí)行完畢,通知 WaitGroup
    fmt.Printf("Worker %d starting\n", id)
    time.Sleep(time.Second) // 模擬耗時(shí)操作
    fmt.Printf("Worker %d done\n", id)
}

func main() {
    var wg sync.WaitGroup

    for i := 1; i <= 5; i++ {
        wg.Add(1) // 啟動(dòng)一個(gè) goroutine 前調(diào)用 Add(1)
        go worker(i, &wg)
    }

    wg.Wait() // 阻塞直到所有 Done() 被調(diào)用
    fmt.Println("所有任務(wù)已完成")
}

輸出示例

Worker 1 starting
Worker 2 starting
Worker 3 starting
Worker 4 starting
Worker 5 starting
Worker 2 done
Worker 4 done
Worker 1 done
Worker 3 done
Worker 5 done
所有任務(wù)已完成

輸出順序可能每次不同,因?yàn)?goroutine 是并發(fā)執(zhí)行的。

四、使用建議與注意事項(xiàng)

? 正確使用方式:

  • Add(n) 必須在 啟動(dòng) goroutine 之前 調(diào)用。
  • 每個(gè) goroutine 結(jié)束時(shí)必須調(diào)用 Done()。
  • Wait() 通常放在主 goroutine 中,阻塞直到所有任務(wù)完成。

?? 易犯錯(cuò)誤:

  1. 1. 忘記 Done()

    go func() {
        fmt.Println("hello")
        // 忘記 wg.Done(),會(huì)導(dǎo)致 wg.Wait() 永久阻塞
    }()
    
  2. 2. 在 goroutine 內(nèi)調(diào)用 Add()

    go func() {
        wg.Add(1) // ?不推薦:會(huì)出現(xiàn)數(shù)據(jù)競(jìng)爭(zhēng)
        ...
    }()
    

    正確方式是主 goroutine 中統(tǒng)一 Add()。

五、封裝使用:任務(wù)調(diào)度器

我們可以封裝一個(gè)并發(fā)調(diào)度器,更加靈活:

type TaskScheduler struct {
    wg sync.WaitGroup
}

func (t *TaskScheduler) Run(task func()) {
    t.wg.Add(1)
    go func() {
        defer t.wg.Done()
        task()
    }()
}

func (t *TaskScheduler) Wait() {
    t.wg.Wait()
}

使用示例:

func main() {
    scheduler := TaskScheduler{}

    for i := 0; i < 5; i++ {
        index := i
        scheduler.Run(func() {
            fmt.Printf("Task %d running\n", index)
            time.Sleep(500 * time.Millisecond)
        })
    }

    scheduler.Wait()
    fmt.Println("All scheduled tasks completed.")
}

六、與其他同步機(jī)制對(duì)比

同步機(jī)制用途
sync.WaitGroup等待一組協(xié)程結(jié)束
sync.Mutex保護(hù)共享資源
sync.Once只執(zhí)行一次的操作(如初始化)
channel通信為主,也可用于同步控制

七、結(jié)語(yǔ)

在并發(fā)控制中,sync.WaitGroup 是一種簡(jiǎn)單卻非常強(qiáng)大的工具,能幫助我們控制 goroutine 的生命周期,避免程序提前退出或資源泄漏等問(wèn)題。掌握其使用方法,是每位 Go 開(kāi)發(fā)者的必備技能。

? 實(shí)戰(zhàn)建議:在進(jìn)行網(wǎng)絡(luò)抓取、任務(wù)分發(fā)、并發(fā)計(jì)算等場(chǎng)景時(shí),推薦優(yōu)先考慮 WaitGroup 來(lái)管理協(xié)程。

到此這篇關(guān)于Go語(yǔ)言使用WaitGroup等待多個(gè)協(xié)程完成的文章就介紹到這了,更多相關(guān)Go WaitGroup等待多協(xié)程完成內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • Golang 零值、空值與空結(jié)構(gòu)的使用小結(jié)

    Golang 零值、空值與空結(jié)構(gòu)的使用小結(jié)

    本文主要介紹了Golang 零值、空值與空結(jié)構(gòu)的使用小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2026-02-02
  • vscode搭建go開(kāi)發(fā)環(huán)境案例詳解

    vscode搭建go開(kāi)發(fā)環(huán)境案例詳解

    對(duì)于Visual Studio Code開(kāi)發(fā)工具,有一款優(yōu)秀的GoLang插件,今天通過(guò)本文給大家介紹下vscode搭建go開(kāi)發(fā)環(huán)境的詳細(xì)教程,感興趣的朋友跟隨小編一起看看吧
    2021-12-12
  • 使用Go?http重試請(qǐng)求的示例

    使用Go?http重試請(qǐng)求的示例

    開(kāi)發(fā)中對(duì)于http請(qǐng)求是經(jīng)常遇到,一般可能網(wǎng)絡(luò)延遲或接口返回超時(shí),這篇文章主要介紹了使用Go?http重試請(qǐng)求的示例,需要的朋友可以參考下
    2022-08-08
  • Go代碼檢查的推薦工具及使用詳解

    Go代碼檢查的推薦工具及使用詳解

    這篇文章主要為大家介紹了Go代碼檢查的推薦工具及使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • gin框架中使用JWT的定義需求及解析

    gin框架中使用JWT的定義需求及解析

    這篇文章主要為介紹了gin框架中使用JWT的定義需求及解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • Go map排序的實(shí)現(xiàn)示例

    Go map排序的實(shí)現(xiàn)示例

    map默認(rèn)是無(wú)序的,不管是按照key還是按照value默認(rèn)都不排序,本文主要介紹了Go map排序的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • go使用errors.Wrapf()代替log.Error()方法示例

    go使用errors.Wrapf()代替log.Error()方法示例

    這篇文章主要為大家介紹了go使用errors.Wrapf()代替log.Error()的方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • 詳解以go思想去處理js異常拋棄trycatch

    詳解以go思想去處理js異常拋棄trycatch

    這篇文章主要為大家介紹了詳解以go思想去處理js異常拋棄trycatch,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Go并發(fā)讀寫(xiě)文件、分片寫(xiě)、分片下載文件的實(shí)現(xiàn)示例

    Go并發(fā)讀寫(xiě)文件、分片寫(xiě)、分片下載文件的實(shí)現(xiàn)示例

    讀寫(xiě)文件在很多項(xiàng)目中都可以用到,本文主要介紹了Go并發(fā)讀寫(xiě)文件、分片寫(xiě)、分片下載文件的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • Go語(yǔ)言常用的打log方式詳解

    Go語(yǔ)言常用的打log方式詳解

    Golang的log包短小精悍,可以非常輕松的實(shí)現(xiàn)日志打印轉(zhuǎn)存功能,下面這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言常用的打log方式的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-10-10

最新評(píng)論

永昌县| 余干县| 海原县| 虞城县| 墨玉县| 滦南县| 张家口市| 平和县| 隆尧县| 庆云县| 仪征市| 大竹县| 高青县| 海晏县| 分宜县| 芒康县| 姚安县| 锡林浩特市| 台北县| 安徽省| 玉田县| 商洛市| 军事| 翼城县| 嘉兴市| 嫩江县| 远安县| 江达县| 潮州市| 那曲县| 大埔区| 崇礼县| 永顺县| 中超| 湾仔区| 五寨县| 昆明市| 六安市| 绥芬河市| 沈阳市| 进贤县|