Go基礎系列:WaitGroup用法說明

来源:https://www.cnblogs.com/f-ck-need-u/archive/2018/11/22/10004787.html
-Advertisement-
Play Games

正常情況下,新激活的goroutine的結束過程是不可控制的,唯一可以保證終止goroutine的行為是main goroutine的終止。也就是說,我們並不知道哪個goroutine什麼時候結束。 但很多情況下,我們正需要知道goroutine是否完成。這需要藉助sync包的WaitGroup來實 ...


正常情況下,新激活的goroutine的結束過程是不可控制的,唯一可以保證終止goroutine的行為是main goroutine的終止。也就是說,我們並不知道哪個goroutine什麼時候結束。

但很多情況下,我們正需要知道goroutine是否完成。這需要藉助sync包的WaitGroup來實現。

WatiGroup是sync包中的一個struct類型,用來收集需要等待執行完成的goroutine。下麵是它的定義:

type WaitGroup struct {
        // Has unexported fields.
}
    A WaitGroup waits for a collection of goroutines to finish. The main
    goroutine calls Add to set the number of goroutines to wait for. Then each
    of the goroutines runs and calls Done when finished. At the same time, Wait
    can be used to block until all goroutines have finished.

    A WaitGroup must not be copied after first use.


func (wg *WaitGroup) Add(delta int)
func (wg *WaitGroup) Done()
func (wg *WaitGroup) Wait()

它有3個方法:

  • Add():每次激活想要被等待完成的goroutine之前,先調用Add(),用來設置或添加要等待完成的goroutine數量
    • 例如Add(2)或者兩次調用Add(1)都會設置等待計數器的值為2,表示要等待2個goroutine完成
  • Done():每次需要等待的goroutine在真正完成之前,應該調用該方法來人為表示goroutine完成了,該方法會對等待計數器減1
  • Wait():在等待計數器減為0之前,Wait()會一直阻塞當前的goroutine

也就是說,Add()用來增加要等待的goroutine的數量,Done()用來表示goroutine已經完成了,減少一次計數器,Wait()用來等待所有需要等待的goroutine完成。

下麵是一個示例,通過示例很容易理解。

package main

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

func process(i int, wg *sync.WaitGroup) {  
    fmt.Println("started Goroutine ", i)
    time.Sleep(2 * time.Second)
    fmt.Printf("Goroutine %d ended\n", i)
    wg.Done()
}

func main() {  
    no := 3
    var wg sync.WaitGroup
    for i := 0; i < no; i++ {
        wg.Add(1)
        go process(i, &wg)
    }
    wg.Wait()
    fmt.Println("All go routines finished executing")
}

上面激活了3個goroutine,每次激活goroutine之前,都先調用Add()方法增加一個需要等待的goroutine計數。每個goroutine都運行process()函數,這個函數在執行完成時需要調用Done()方法來表示goroutine的結束。激活3個goroutine後,main goroutine會執行到Wait(),由於每個激活的goroutine運行的process()都需要睡眠2秒,所以main goroutine在Wait()這裡會阻塞一段時間(大約2秒),當所有goroutine都完成後,等待計數器減為0,Wait()將不再阻塞,於是main goroutine得以執行後面的Println()。

還有一點需要特別註意的是process()中使用指針類型的*sync.WaitGroup作為參數,這裡不能使用值類型的sync.WaitGroup作為參數,因為這意味著每個goroutine都拷貝一份wg,每個goroutine都使用自己的wg。這顯然是不合理的,這3個goroutine應該共用一個wg,才能知道這3個goroutine都完成了。實際上,如果使用值類型的參數,main goroutine將會永久阻塞而導致產生死鎖。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.Map 遍歷: 2.map的長度: int size=Map.size(); ...
  • 前言 網際網路聯繫的是世界各地的電腦(通過電纜),萬維網聯繫的是網上的各種各樣資源(通過文本超鏈接),如靜態的HTML文件,動態的軟體程式······。由於萬維網的存在,處於網際網路中的每台電腦可以很方便地進行消息交流、文件資源交流······。基於網際網路的幫助,我們可以在web客戶端(如瀏覽器等) ...
  • FileManager 圖片管理插件是 TinyMCE下 免費且非官方的文件插件,可上傳/管理的類型包括:文件,圖片,視頻。 本教程主要展示大叔在為安裝開發插件過程中進行調整的修改記錄。 ...
  • 昨天是感恩節,上幼兒園的女兒在老師的叮囑下,晚上為我和老婆洗了腳(形式上的^_^),還給我們每人端了一杯水。看著孩子一天天的長大,懂事,感覺很開心。話說咱們程式員這麼辛苦是為了什麼?不就是為了老婆,孩子,熱炕頭,有一個溫暖幸福的家庭,再捎帶著用代碼改變一下世界嗎?想到這裡,頓時覺得學習,創作博客的勁... ...
  • 有人說,你應該關註時事、財經,甚至流行的電影、電視劇,才有可能趁著熱點寫出爆文;有人說,你別再寫“無聊”的技術文了,因為程式員的圈子真的很小,即便是像鴻祥那樣的招牌大牛,文章是那麼的乾貨,瀏覽量有多少?不到萬吧;有人說,你別妄想在寫作上面知識變現了,因為你寫的文章真的很不優秀,我都不愛看! 我想說, ...
  • Django中每一個模型model都對應於資料庫中的一張表,每個模型中的欄位都對應於資料庫表的列。方便的是,django可以自動生成這些create table, alter table, drop table的操作。其次Django為咱們也提供了後臺管理模塊(Django-Admin),主要功能是 ...
  • 原地址:https://www.cnblogs.com/hongten/p/hongten_java_sleep_wait.html ...
  • 1.網路通信協議 osi七層模型:按照分工不同把互聯網協議從邏輯上劃分了層級 socket層 2.理解socket: Socket是應用層與TCP/IP協議族通信的中間軟體抽象層,它是一組介面。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket介面後面,對 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...