Rumah >pembangunan bahagian belakang >Golang >Go Channels: Mengapa Tamat Masa Saya dalam Pernyataan `pilih` Tidak Pernah Dicetuskan?
Go Channels: Mengapa Tamat Masa Kekal Tidak Dilaksanakan
Pertimbangkan senario di mana goroutin dan saluran digunakan seperti dalam coretan kod di bawah. Mengapa senario tamat masa tidak pernah menjadi kenyataan?
func main() { c1 := make(chan int, 1) go func() { for { time.Sleep(1500 * time.Millisecond) c1 <- 10 } }() go func() { for { select { case i := <-c1: fmt.Println(i) case <-time.After(2000 * time.Millisecond): fmt.Println("TIMEOUT") // Not Executed } } }() fmt.Scanln() }
Analisis
Senario tamat masa tidak berlaku kerana goroutine secara berterusan menghantar nilai ke saluran c1 kira-kira setiap 1.5 saat . Tamat masa hanya akan berkuat kuasa jika tiada nilai diterima daripada c1 selama 2 saat.
Walau bagaimanapun, apabila menerima nilai daripada c1, masa baharu. Selepas panggilan dibuat dalam pelaksanaan pilihan seterusnya, menjana saluran baharu di mana nilai hanya akan dikeluarkan selepas 2 saat lagi. Saluran tamat masa daripada pelaksanaan pilihan sebelumnya dibuang, menjadikannya tidak berkesan.
Penyelesaian
Untuk menangani isu ini, saluran tamat masa hendaklah dibuat sekali sahaja, dengan berkesan:
timeout := time.After(2000 * time.Millisecond) for { select { case i := <-c1: fmt.Println(i) case <-timeout: fmt.Println("TIMEOUT") // Will be printed after 2 seconds } }
Output
Kod yang diubah suai kemudiannya mencetak:
10 TIMEOUT 10 10 10 ...
Oleh itu, senario tamat masa kini berjaya dilaksanakan selepas 2 saat, mencerminkan tingkah laku yang dimaksudkan.
Atas ialah kandungan terperinci Go Channels: Mengapa Tamat Masa Saya dalam Pernyataan `pilih` Tidak Pernah Dicetuskan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!