Kebuntuan dalam Go dengan WaitGroup dan Saluran Penimbalan
Dalam Go, jalan buntu berlaku apabila berbilang gorout sedang menunggu satu sama lain untuk selesai, mengakibatkan dalam kebuntuan. Keadaan ini boleh timbul apabila menggunakan saluran penimbal dan WaitGroups secara tidak betul.
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 return }() } wg.Wait() for c := range ch { fmt.Printf("c is %v", c) } }</code>
Kod ini dijangka akan mencipta saluran dengan saiz penimbal 4 dan memulakan 5 gorouti , masing-masing menghantar kepingan kosong ke saluran. Goroutine utama menunggu sehingga semua goroutine selesai dan kemudian berjulat di atas saluran.
Walau bagaimanapun, kod ini akan mengakibatkan kebuntuan. Mengapa?
Punca Kebuntuan:
Dua masalah wujud dalam kod:
Penyelesaian:
Tingkatkan Kapasiti Saluran: Dengan meningkatkan kapasiti saluran kepada 5, slot yang mencukupi akan tersedia untuk semua gorout menghantar nilai mereka tanpa menyekat. Selain itu, menutup saluran selepas goroutine selesai menulis akan memberi isyarat kepada gelung julat bahawa tiada lagi elemen akan datang, menghalangnya daripada menunggu selama-lamanya.
<code class="go">ch := make(chan []int, 5) ... wg.Wait() close(ch)</code>
Gunakan Selesai () dalam Gelung: Daripada menutup saluran, seseorang boleh menggunakan kaedah Done() WaitGroup untuk memberi isyarat apabila goroutine terakhir telah selesai. Dengan memanggil Done() dalam gelung julat, goroutine utama akan dimaklumkan apabila saluran kosong dan gelung boleh keluar.
<code class="go">go func() { for c := range ch { fmt.Printf("c is %v\n", c) wg.Done() } }() wg.Wait()</code>
Penyelesaian ini menyelesaikan kebuntuan dengan memastikan bahawa saluran mempunyai kapasiti yang mencukupi dan gelung julat keluar apabila tiada lagi elemen untuk dibaca daripada saluran.
Atas ialah kandungan terperinci Mengapakah kod Go yang disediakan dengan WaitGroup dan saluran penimbal mengakibatkan kebuntuan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!