Masalah:
Dalam latihan Go Tour #71, menggunakan go run 71_hang.go hasil tidak baik dalam program berjalan selama-lamanya, manakala go run 71_hang.go ok berfungsi seperti yang diharapkan. Satu-satunya perbezaan ialah penambahan fmt.Print("") dalam kes lalai bagi pernyataan pilih.
Penjelasan:
Pernyataan lalai dalam perubahan pilihan tingkah laku penyataan tersebut. Tanpa lalai, pilih blok sehingga terdapat mesej pada saluran. Dengan lalai, pilih melaksanakan pernyataan lalai setiap kali tiada apa-apa untuk dibaca daripada saluran.
Dalam kod asal, pernyataan lalai mencipta gelung tak terhingga. Memandangkan penjadual tidak boleh menjadualkan goroutine lain, atur cara berjalan selama-lamanya.
Penyelesaian 1:
Alih keluar pernyataan lalai dan gunakan pilihan bukan sekatan:
for { select { case todo := <-toDoList: if todo.depth > 0 && !visited[todo.url] { crawling++ visited[todo.url] = true go crawl(todo, fetcher, toDoList, doneCrawling) } case <-doneCrawling: crawling-- } if crawling == 0 { break } }
Penyelesaian 2:
Kekalkan pernyataan lalai tetapi pastikan goroutine menghasilkan. Satu cara untuk mencapai matlamat ini ialah dengan menggunakan GOMAXPROCS=2, yang membenarkan penjadual menggunakan berbilang teras.
Nota Tambahan:
Gorutin dijadualkan secara kerjasama. Pilih ialah titik di mana goroutine harus menghasilkan. Walau bagaimanapun, dalam contoh yang diberikan, sebab pilih tidak menghasilkan tanpa pernyataan fmt.Print() tidak difahami sepenuhnya dan memerlukan penyiasatan lanjut.
Atas ialah kandungan terperinci Mengapa Pernyataan `pilih` Go Digantung Tanpa Kes `lalai` dan Bagaimana Ia Boleh Dibetulkan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!