Rumah >pembangunan bahagian belakang >Golang >Go Channels: Mengapa Tamat Masa Saya dalam Pernyataan `pilih` Tidak Pernah Dicetuskan?

Go Channels: Mengapa Tamat Masa Saya dalam Pernyataan `pilih` Tidak Pernah Dicetuskan?

DDD
DDDasal
2024-12-26 03:37:09404semak imbas

Go Channels: Why Doesn't My Timeout in a `select` Statement Ever Trigger?

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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn