首頁 >後端開發 >Golang >為什麼我的 Go 逾時在此通道範例中不起作用?

為什麼我的 Go 逾時在此通道範例中不起作用?

DDD
DDD原創
2024-11-08 17:48:02771瀏覽

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

Go:在通道中使用超時

在Go 中,超時和通道提供了一種方便的方法來控制goroutine 的執行並同步其結果。但是,在某些情況下,超時情況可能不會如預期執行。

問題陳述

考慮以下Go 代碼:

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

此程式碼的目標是檢查提供的清單中的所有URL 是否均可訪問。如果任何 URL 在一秒內未能回應,則函數應該會傳回 false。

但是,當執行此程式碼時,它將始終傳回 true。超時情況未執行。

說明

問題是由於 check(u) 的執行方式而產生的。在 IsReachable 函數中,每個 goroutine 透過呼叫 check(u) 檢查 URL 的可及性。然而, check(u) 在返回之前會在當前 goroutine 中休眠 4 秒。

在 select 語句中, case ch

解決方案

要解決此問題,應執行 check(u) 函數在一個單獨的 goroutine 中。這使得 select 語句能夠正確處理逾時情況。

這是更新後的程式碼:

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

現在,如果任何 URL 無法在一秒鐘內回應,函數將傳回錯誤的。此外,如果只有一個 URL 可用,則函數將傳回 true。

以上是為什麼我的 Go 逾時在此通道範例中不起作用?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn