91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Golang中WaitGroup陷阱的示例分析

發布時間:2021-09-14 17:38:31 來源:億速云 閱讀:108 作者:小新 欄目:編程語言

這篇文章給大家分享的是有關Golang中WaitGroup陷阱的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

sync.WaitGroup是并發環境中,一個相當常用的數據結構,用來等待所有協程的結束,在寫代碼的時候都是按著例子的樣子寫的,也沒用深究過它的使用。前幾日想著能不能在協程中執行Add()函數,答案是不能,這里介紹下。

陷阱在WaitGroup的3個函數的調用順序上。先回顧下3個函數的功能:

  1. Add(delta int):給計數器增加delta,比如啟動1個協程就增加1。

  2. Done():協程退出前執行,把計數器減1。

  3. Wait():阻塞等待計數器為0。

考一考

下面的程序是創建了協程father,然后father協程創建了10個子協程,main函數等待所有協程結束后退出,看看下面代碼有沒有什么問題?

package main

import (
    "fmt"
    "sync"
)

func father(wg *sync.WaitGroup) {
    wg.Add(1)
    defer wg.Done()

    fmt.Printf("father\n")
    for i := 0; i < 10; i++ {
        go child(wg, i)
    }
}

func child(wg *sync.WaitGroup, id int) {
    wg.Add(1)
    defer wg.Done()

    fmt.Printf("child [%d]\n", id)
}

func main() {
    var wg sync.WaitGroup
    go father(&wg)

    wg.Wait()
    log.Printf("main: father and all chindren exit")
}

發現問題了嗎?如果沒有看下面的運行結果:main函數在子協程結束前就開始結束了。

father
main: father and all chindren exit
child [9]
child [0]
child [4]
child [7]
child [8]

陷阱分析

產生以上問題的原因在于,創建協程后在協程內才執行Add()函數,而此時Wait()函數可能已經在執行,甚至Wait()函數在所有Add()執行前就執行了,Wait()執行時立馬就滿足了WaitGroup的計數器為0,Wait結束,主程序退出,導致所有子協程還沒完全退出,main函數就結束了。

正確的做法

Add函數一定要在Wait函數執行前執行,這在Add函數的文檔中就提示了: Note that calls with a positive delta that occur when the counter is zero must happen before a Wait.

如何確保Add函數一定在Wait函數前執行呢?在協程情況下,我們不能預知協程中代碼執行的時間是否早于Wait函數的執行時間,但是,我們可以在分配協程前就執行Add函數,然后再執行Wait函數,以此確保。

下面是修改后的程序,以及輸出結果。

package main

import (
    "fmt"
    "sync"
)

func father(wg *sync.WaitGroup) {
    defer wg.Done()

    fmt.Printf("father\n")
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go child(wg, i)
    }
}

func child(wg *sync.WaitGroup, id int) {
    defer wg.Done()
    fmt.Printf("child [%d]\n", id)
}

func main() {
    var wg sync.WaitGroup
    wg.Add(1)
    go father(&wg)

    wg.Wait()
    fmt.Println("main: father and all chindren exit")
}
father
child [9]
child [7]
child [8]
child [1]
child [4]
child [5]
child [2]
child [6]
child [0]
child [3]
main: father and all chindren exit

感謝各位的閱讀!關于“Golang中WaitGroup陷阱的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

油尖旺区| 阳高县| 札达县| 昆明市| 南投县| 宁蒗| 巧家县| 东台市| 阳新县| 慈溪市| 平阴县| 静安区| 怀安县| 永仁县| 郸城县| 深州市| 江川县| 和顺县| 天全县| 呼伦贝尔市| 琼海市| 红桥区| 泗水县| 香河县| 寿阳县| 和龙市| 泸州市| 九寨沟县| 手机| 吉水县| 六枝特区| 隆昌县| 湖南省| 眉山市| 宕昌县| 大同县| 勐海县| 岑溪市| 井冈山市| 通化市| 边坝县|