Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapa Tamat Masa Pergi Saya Tidak Berfungsi dalam Contoh Saluran ini?

Mengapa Tamat Masa Pergi Saya Tidak Berfungsi dalam Contoh Saluran ini?

DDD
DDDasal
2024-11-08 17:48:02677semak imbas

Why Does My Go Timeout Not Work in this Channel Example?

Go: Menggunakan Tamat Masa dengan Saluran

Dalam Go, tamat masa dan saluran menyediakan cara yang mudah untuk mengawal pelaksanaan goroutin dan menyegerakkan keputusannya . Walau bagaimanapun, terdapat senario tertentu di mana kes tamat masa mungkin tidak dilaksanakan seperti yang dijangkakan.

Pernyataan Masalah

Pertimbangkan kod Go berikut:

import "fmt"
import "time"

func check(u string) bool {
    time.Sleep(4 * time.Second)
    return true
}

func IsReachable(urls []string) bool {

    ch := make(chan bool, 1)
    for _, url := range urls {
        go func(u string) {
            select {
            case ch <- check(u):
            case <-time.After(time.Second):
                ch <- false
            }
        }(url)
    }
    return <-ch
}
func main() {
    fmt.Println(IsReachable([]string{"url1"}))
}

Matlamat kod ini adalah untuk menyemak sama ada semua URL dalam senarai yang disediakan boleh dicapai. Jika mana-mana URL gagal bertindak balas dalam masa sesaat, fungsi itu harus mengembalikan palsu.

Walau bagaimanapun, apabila melaksanakan kod ini, ia akan sentiasa kembali benar. Kes tamat masa tidak dapat dilaksanakan.

Penjelasan

Isu ini timbul kerana cara semak(u) dilaksanakan. Dalam fungsi IsReachable, setiap goroutine menyemak kebolehcapaian URL dengan memanggil check(u). Walau bagaimanapun, check(u) tidur selama 4 saat dalam goroutine semasa sebelum kembali.

Dalam penyataan pilih, kes ch <- check(u): branch ialah yang pertama tersedia, sebagai check( u) telah pun kembali. Ini menghalang kes tamat masa daripada pernah dilaksanakan, menyebabkan fungsi sentiasa kembali benar.

Penyelesaian

Untuk menyelesaikan isu ini, fungsi check(u) harus dilaksanakan dalam goroutine yang berasingan. Ini membolehkan penyataan pilih mengendalikan kes tamat masa dengan betul.

Berikut ialah kod yang dikemas kini:

import "fmt"
import "time"

func check(u string, checked chan<- bool) {
    time.Sleep(4 * time.Second)
    checked <- true
}

func IsReachable(urls []string) bool {

    ch := make(chan bool, 1)
    for _, url := range urls {
        go func(u string) {
            checked := make(chan bool)
            go check(u, checked)
            select {
            case ret := <-checked:
                ch <- ret
            case <-time.After(1 * time.Second):
                ch <- false
            }
        }(url)
    }
    return <-ch
}
func main() {
    fmt.Println(IsReachable([]string{"url1"}))
}

Sekarang, jika mana-mana URL gagal bertindak balas dalam masa sesaat, fungsi akan kembali palsu. Selain itu, jika hanya satu URL tersedia, fungsi itu akan kembali benar.

Atas ialah kandungan terperinci Mengapa Tamat Masa Pergi Saya Tidak Berfungsi dalam Contoh Saluran ini?. 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