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
Susan Sarandonasal
2024-12-14 20:56:21219semak imbas

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
}

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")
    }
}

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!

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