Pengesanan Deadlock dalam Go Concurrency dengan WaitGroups
Dalam Go, concurrency selalunya diurus menggunakan saluran dan kumpulan tunggu untuk mengatur gorout. Walau bagaimanapun, adalah penting untuk memahami kemungkinan perangkap yang boleh membawa kepada kebuntuan.
Penerangan Masalah
Pertimbangkan kod berikut yang cuba menggunakan saluran penimbal dan kumpulan tunggu:
<code class="go">package main import ( "fmt" "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 // Send to channel return }() } wg.Wait() // Wait for all goroutines to complete for c := range ch { fmt.Printf("c is %v", c) // Iterate over channel } }</code>
Walaupun menjangkakan saluran akan ditutup secara automatik setelah kapasitinya dicapai, kod ini secara tidak dijangka mengakibatkan ralat jalan buntu.
Penyelesaian
Terdapat dua isu utama yang membawa kepada kebuntuan:
Untuk menyelesaikan kebuntuan, dua penyelesaian ialah:
Penyelesaian 1: Meluaskan Kapasiti Saluran dan Penutupan Secara Eksplisit
<code class="go">ch := make(chan []int, 5) // Increase channel capacity ... wg.Wait() close(ch) // Close the channel to stop range loop</code>
Ini memastikan terdapat ruang yang mencukupi dalam saluran dan menutupnya secara eksplisit, membolehkan gelung julat ditamatkan.
Penyelesaian 2: Keadaan Isyarat Selesai dalam Goroutine
<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() // Signal completion within goroutine return }() } go func() { for c := range ch { fmt.Printf("c is %v\n", c) wg.Done() //Decrement count for each iteration } }() wg.Wait() }</code>
Dalam penyelesaian ini, setiap goroutine menandakan siapnya dengan memanggil wg.Done() dalam goroutine itu sendiri. Kumpulan tunggu juga dikurangkan dalam gelung julat untuk setiap lelaran, memastikan wg.Wait() akhirnya selesai dan program ditamatkan.
Atas ialah kandungan terperinci Bagaimanakah Kebuntuan Boleh Berlaku Apabila Menggunakan WaitGroups dan Saluran Penimbalan dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!