在並發程式設計領域,Goroutines 和通道在實現非同步通訊模式中發揮關鍵作用。然而,理解它們如何與超時互動可能有點棘手。
考慮以下程式碼片段:
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 <p>此程式碼的目標是確定 URL 清單是否可存取。但是,無論是否有任何 URL 無法訪問,它始終會傳回 true。為什麼超時情況沒有被執行? </p><p>理解這個問題的關鍵在於 Goroutine 和 Channels 是如何互動的。當在外部 Goroutine 中呼叫 check(u) 時,它會暫停該 Goroutine 的執行 4 秒。但是,select 語句僅在 check(u) 傳回後執行。到那時, check(u) 和 time.After 分支都已準備好運行。 </p><p>為了解決這個問題,我們需要將check(u) 隔離在它自己的Goroutine 中:</p><pre class="brush:php;toolbar:false">import "fmt" import "time" func check(u string, checked chan <p>在此修改後的程式碼中,check(u) 在單獨的Goroutine 中調用。這允許 select 語句正確區分 check(u) 的完成和逾時條件。 </p><p>或者,我們可以透過對所有 URL 使用單一超時來簡化程式碼:</p><pre class="brush:php;toolbar:false">import "fmt" import "time" func check(u string, ch chan<p>在此版本中,我們使用一個可以保存所有回應的通道。設定超時時間為一秒,返回通道中第一個到達的結果。如果在逾時到期之前無法存取任何 URL,則通道將收到 false 值。 </p>
以上是為什麼 Go Channel 使用 Goroutine 會逾時失敗?的詳細內容。更多資訊請關注PHP中文網其他相關文章!