Kebuntuan dalam Go: WaitGroup dan Saluran Buffered
Dalam Go, kebuntuan berlaku apabila gorout serentak menunggu selama-lamanya untuk satu sama lain selesai. Satu punca biasa kebuntuan melibatkan penggunaan WaitGroups dan saluran penimbal.
Contoh Kebuntuan
Pertimbangkan kod berikut:
<code class="go">package main import "fmt" import "sync" func main() { ch := make(chan []int, 4) var m []int var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { defer wg.Done() ch <- m // Sending to a full channel return }() } wg.Wait() for c := range ch { fmt.Printf("c is %v", c) } }</code>
Kod ini berhasrat untuk menghantar 5 keping kosong ke saluran penimbal dengan kapasiti 4 dan kemudian dibaca dari saluran selepas semua goroutine selesai. Walau bagaimanapun, kod tersebut mengakibatkan ralat kebuntuan.
Punca Kebuntuan
Kebuntuan timbul disebabkan oleh dua isu:
Penyelesaian
Untuk menyelesaikan kebuntuan, buat salah satu daripada pengubahsuaian berikut:
Penyelesaian 1:
Tingkatkan kapasiti saluran kepada 5 (atau lebih) dan tutupnya selepas menghantar semua data :
<code class="go">ch := make(chan []int, 5) ... wg.Wait() close(ch)</code>
Penyelesaian 2:
Mulakan goroutine berasingan untuk membaca daripada saluran dan maklumkan goroutine utama apabila semua data telah diterima:
<code class="go">func main() { ch := make(chan []int, 4) var m []int var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { ch <- m wg.Done() }() } go func() { for c := range ch { fmt.Printf("c is %v\n", c) wg.Done() } }() wg.Wait() }</code>
Atas ialah kandungan terperinci Bagaimanakah saya boleh mengelakkan kebuntuan apabila menggunakan WaitGroups dan saluran penimbal dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!