Rumah >pembangunan bahagian belakang >Golang >Mengapa Saluran Tidak Dibuffer dalam Pergi Menyebabkan Kebuntuan?
Kebuntuan dalam Saluran Tidak Dibuffer di Goroutines
Dalam model konkurensi Go, saluran yang tidak ditimbal boleh membawa kepada kebuntuan yang tidak dijangka. Mari kita selidiki sebab perkara ini berlaku dan terokai penyelesaian alternatif.
Pertimbangkan coretan kod berikut:
package main import "fmt" func main() { c := make(chan int) c <- 1 fmt.Println(<-c) }
Kod ini nampaknya melakukan operasi hantar dan terima yang mudah pada saluran yang tidak ditimbal. Walau bagaimanapun, apabila dijalankan, ia mengakibatkan jalan buntu dengan ralat berikut:
fatal error: all goroutines are asleep - deadlock! goroutine 1 [chan send]: main.main() /home/tarrsalah/src/go/src/github.com/tarrsalah/tour.golang.org/65.go:8 +0x52 exit status 2
Untuk memahami sebab kebuntuan ini berlaku, kita mesti terlebih dahulu memahami kelakuan saluran tidak buffer.
Menyelidiki Saluran Tidak Dibuffer
Seperti yang didokumenkan dalam dokumentasi rasmi Go, "Jika saluran itu unbuffered, penghantar menyekat sehingga penerima telah menerima nilai Jika saluran mempunyai penimbal, penghantar menyekat hanya sehingga nilai telah disalin ke penimbal, ini bermakna menunggu sehingga beberapa penerima telah mendapatkan nilai ."
Dalam istilah yang lebih mudah:
Senario Kebuntuan
Dalam memberikan coretan kod, operasi c <- 1 blok kerana saluran tidak dibuffer dan tiada yang lain goroutine wujud untuk menerima nilai yang dihantar. Akibatnya, program menemui jalan buntu.
Memecah Kebuntuan
Untuk menyelesaikan kebuntuan, kita boleh sama ada:
ATAU
Contoh dengan Goroutine Penerima:
package main import "fmt" func main() { c := make(chan int) go func() { fmt.Println("received:", <-c) }() c <- 1 }
Di sini, goroutine yang dibuat dengan go func() {...} akan terus menunggu untuk menerima nilai daripada saluran. Dengan memperkenalkan goroutine penerima ini, kebuntuan dapat dicegah.
Kesimpulannya, menggunakan saluran yang tidak dibuffer dalam goroutine yang sama tanpa mekanisme penerimaan yang khusus boleh menyebabkan kebuntuan. Untuk mengelakkan perkara ini, pertimbangkan untuk menggunakan saluran penimbal atau memperkenalkan goroutin penerimaan yang berasingan untuk memastikan pemindahan data yang betul antara gorouti serentak.
Atas ialah kandungan terperinci Mengapa Saluran Tidak Dibuffer dalam Pergi Menyebabkan Kebuntuan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!