Apabila cuba menyelaraskan penyiapan berbilang goroutin menggunakan penyegerakan.WaitGroup , seseorang mungkin menghadapi ralat "ralat maut: semua goroutine sedang tidur - kebuntuan!" Mesej samar ini boleh membingungkan, terutamanya apabila kod kelihatan seperti ditulis mengikut contoh dokumentasi.
Punca ralat ini terletak pada cara Go mengendalikan nilai yang dihantar kepada fungsi. Apabila menghantar objek sync.WaitGroup secara langsung, Go mencipta salinan nilai itu, pada asasnya menghantar objek berbeza kepada setiap goroutine. Ini mewujudkan pemutusan sambungan antara WaitGroup asal dan salinan yang dikendalikan oleh goroutine.
Penyelesaian kepada isu ini ialah dengan menghantar penuding kepada penyegerakan.WaitGroup sebaliknya. Dengan berbuat demikian, semua goroutine akan merujuk objek asas yang sama dan beroperasi pada kaunter dalamannya secara konsisten. Kod yang betul menggunakan penuding disediakan di bawah:
import "sync" func doWork(wg *sync.WaitGroup) error { defer wg.Done() // Do some heavy lifting... request URL's or similar return nil } func main() { wg := &sync.WaitGroup{} // Use pointer to pass the WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go doWork(wg) } }
Dengan perubahan ini, goroutine akan berinteraksi dengan betul dengan objek WaitGroup, menambah pembilangnya sebelum memulakan kerja mereka dan mengurangkannya apabila selesai. Akibatnya, panggilan WaitGroup.Wait() dalam fungsi utama tidak akan menyekat selama-lamanya dan program akan dilaksanakan seperti yang diharapkan.
Atas ialah kandungan terperinci Mengapa Menggunakan `sync.WaitGroup` Membawa kepada 'ralat maut: semua goroutine sedang tidur - kebuntuan!', dan Bagaimana Saya Boleh Membetulkannya?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!