Rumah >pembangunan bahagian belakang >Golang >Mengapakah kod Go yang disediakan dengan WaitGroup dan saluran penimbal mengakibatkan kebuntuan?
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 <p>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.</p> <p>Walau bagaimanapun, kod ini akan mengakibatkan kebuntuan. Mengapa?</p> <p><strong>Punca Kebuntuan:</strong></p> <p>Dua masalah wujud dalam kod:</p> <ol> <li>Kapasiti Saluran: Saluran mempunyai kapasiti sebanyak 4, yang bermaksud ia boleh memuatkan sehingga 4 elemen. Walau bagaimanapun, terdapat 5 goroutine cuba dihantar ke saluran, mengakibatkan situasi di mana goroutine terakhir akan menyekat menunggu slot untuk dibebaskan.</li> <li>Menutup Saluran: Gelung julat ch terus menunggu elemen untuk memasuki saluran. Memandangkan tiada lagi goroutine yang tinggal untuk menulis ke saluran, gelung akan menunggu selama-lamanya.</li> </ol> <p><strong>Penyelesaian:</strong></p> <ol> <li> <p><strong>Tingkatkan Kapasiti Saluran:</strong> 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.</p> <pre class="brush:php;toolbar:false"><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!