首頁  >  文章  >  後端開發  >  為什麼 `wg.Add()` 的放置對於 Go 的 `sync.WaitGroup` 中的正確同步至關重要?

為什麼 `wg.Add()` 的放置對於 Go 的 `sync.WaitGroup` 中的正確同步至關重要?

Linda Hamilton
Linda Hamilton原創
2024-10-30 01:49:02150瀏覽

  Why is the Placement of `wg.Add()` Crucial for Proper Synchronization in Go's `sync.WaitGroup`?

修正 wg.Add() 的 WaitGroup 同步位置

在 Go 中,sync.WaitGroup 型別提供 goroutine 類型提供 goroutine 之間的同步。它的主要目的是讓主 goroutine 等待一組 goroutine 完成任務。然而,wg.Add() 呼叫的放置對於確保正確同步至關重要。

在錯誤的範例中:

<code class="go">var wg sync.WaitGroup
var v int32 = 0
for i := 0; i < 100; i++ {
    go func() {
        wg.Add(1) // Wrong place
        atomic.AddInt32(&v, 1)
        wg.Done()
    }()
}
wg.Wait()
fmt.Println(v)</code>

wg.Add(1) 呼叫放置在匿名函數,這是一個錯誤。這種錯誤的放置可能會導致 wg.Wait() 過早返回的情況,因為 wg.Add(1) 在同一 goroutine 中的 wg.Done() 之後執行。因此,v 將無法準確反映已完成任務的數量,其值可能會小於 100。

在更正的範例中:

<code class="go">var wg sync.WaitGroup
var v int32 = 0
for i := 0; i < 100; i++ {
    wg.Add(1)
    go func() {
        atomic.AddInt32(&v, 1)
        wg.Done()
    }()
}
wg.Wait()
fmt.Println(v)</code>

wg.Add( 1) call 現在被放置在匿名函數之外,確保主goroutine 在呼叫wg.Wait() 之前已經被呼叫了所有100 個goroutine 並向wg 註冊了它們的完成任務。這個正確的放置保證了 wg.Wait() 將阻塞,直到所有 100 個 goroutine 完成其任務,從而獲得準確的 v 值。

使用sync.WaitGroup 的一般規則:

為了確保使用sync.WaitGroup成功同步,請遵循以下準則:

  • 在啟動新的goroutine之前,始終在主goroutine中呼叫wg.Add()。
  • 建議使用 defer 語句呼叫 wg.Done(),以確保即使在發生 Goroutine Panic 時也能執行。
  • 將sync.WaitGroup 傳遞給其他函數時(避免使用包級變數) ),向其傳遞一個指標以防止複製並確保所有更改均對原始的sync.WaitGroup進行。

以上是為什麼 `wg.Add()` 的放置對於 Go 的 `sync.WaitGroup` 中的正確同步至關重要?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn