Rumah > pembangunan bahagian belakang > Golang > Bagaimanakah Saya Boleh Mengatasi Tamat Masa Goroutine Menggunakan Saluran dalam Go?

Bagaimanakah Saya Boleh Mengatasi Tamat Masa Goroutine Menggunakan Saluran dalam Go?

Susan Sarandon
Lepaskan: 2024-12-14 20:56:21
asal
218 orang telah melayarinya

How Can I Reliably Override Goroutine Timeouts Using Channels in Go?

Mengatasi Tamat Masa dalam Goroutines dengan Saluran

Di Golang, apabila menggunakan goroutin dan saluran untuk tugas tak segerak, adalah mungkin untuk menentukan tamat masa untuk memastikan bahawa operasi tidak tergantung selama-lamanya. Walau bagaimanapun, dalam senario tertentu, kes tamat masa mungkin tidak dapat dilaksanakan seperti yang dijangkakan.

Pertimbangkan coretan kod berikut:

package main

import (
    "fmt"
    "time"
)

func main() {
    c1 := make(chan int, 1) // Buffered channel with capacity 1

    go func() {
        for {
            time.Sleep(1500 * time.Millisecond) // Sleep for 1.5 seconds
            c1 <- 10 // Send value to channel
        }
    }()

    go func() {
        for {
            select {
            case i := <-c1:
                fmt.Println(i)
            case <-time.After(2000 * time.Millisecond):
                fmt.Println("TIMEOUT") // Not executed
            }
        }
    }()

    fmt.Scanln() // Wait for user input
}
Salin selepas log masuk

Dalam kod ini, kami mempunyai dua gorout: satu yang menghantar secara berkala nilai kepada saluran penimbal c1, dan satu lagi yang memilih daripada c1 dengan tamat masa 2 saat. Walau bagaimanapun, kes tamat masa ("TIMEOUT") tidak pernah dicetak.

Puncanya terletak pada sifat saluran buffer dan cara tamat masa dikendalikan. Dalam senario ini, goroutine yang menghantar nilai ke c1 akan terus mengisi semula saluran setiap 1.5 saat. Akibatnya, penyataan pilih dalam goroutine kedua akan sentiasa menerima nilai daripada c1 sebelum tamat masa tamat.

Untuk menyelesaikan isu ini dan memastikan kes tamat masa dilaksanakan, kita perlu mencipta saluran tamat masa di luar gelung pilih. Ini menghalangnya daripada dibuang setiap kali nilai diterima daripada c1:

timeout := time.After(2000 * time.Millisecond) // Create timeout channel only once
for {
    select {
    case i := <-c1:
        fmt.Println(i)
    case <-timeout:
        fmt.Println("TIMEOUT")
    }
}
Salin selepas log masuk

Dengan pengubahsuaian ini, penyataan pilih akan terus memilih daripada c1, tetapi jika tiada nilai diterima dalam tempoh tamat masa yang ditentukan, Kes "TIMEOUT" akan dilaksanakan.

Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Mengatasi Tamat Masa Goroutine Menggunakan Saluran dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan