WaitGroup Deadlock: Memahami "Semua Goroutine Sudah Tidur - Deadlock!"
Apabila cuba menyelaraskan goroutine menggunakan WaitGroup, ada kemungkinan untuk ditemui ralat "kesilapan maut: semua goroutine sedang tidur - kebuntuan!". Ini berlaku apabila gorout yang bertanggungjawab untuk mengurangkan kaunter WaitGroup secara tidak sengaja akhirnya tertidur.
Masalahnya:
Kod Go berikut menggambarkan bagaimana ralat ini boleh timbul:
package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() fmt.Println("Hello", i) }() } wg.Wait() }
Setelah dilaksanakan, kod ini harus mencetak "Hello" untuk setiap goroutine. Walau bagaimanapun, sebaliknya, program keluar dengan ralat "kebuntuan" yang ditakuti.
Sebabnya:
Isunya terletak pada cara WaitGroup diserahkan kepada goroutine. Go membuat salinan nilai apabila ia dihantar ke fungsi tanpa nama. Jadi, setiap goroutine beroperasi pada salinan WaitGroup yang berasingan, tiada satu pun daripadanya telah dikurangkan kaunternya, mengakibatkan goroutine tidur selama-lamanya.
Penyelesaian:
Untuk menyelesaikan kebuntuan, penunjuk ke WaitGroup mesti dihantar dan bukannya WaitGroup itu sendiri. Oleh itu, semua goroutine akan merujuk WaitGroup yang sama, membolehkan mereka mengurangkan pembilangnya dengan betul:
package main import ( "fmt" "sync" ) func main() { wg := &sync.WaitGroup{} for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() fmt.Println("Hello", i) }() } wg.Wait() }
Dengan menghantar penuding, goroutine berkongsi objek WaitGroup yang sama dan boleh berjaya menyelaraskan pelaksanaannya. Versi kod ini akan mencetak "Hello" dengan betul untuk setiap goroutine tanpa mencetuskan kebuntuan.
Atas ialah kandungan terperinci Mengapa My Go WaitGroup Menyebabkan 'Semua Goroutine Tidur - Kebuntuan!' Ralat?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!