優先考慮Go select 語句
問題:
問題:問題:
在句號案例塊的評估是不確定的。這可能會導致即使相應的通道已準備好接收,也無法立即輸入特定 case 區塊的情況。
場景:考慮 sendRegularHeartbeats()定期發送心跳訊息並在其上下文被取消時終止的函數。如果在發送第一個心跳訊息之前取消上下文,我們預計不會傳輸任何心跳訊息。
非確定性評估問題:在某些情況下,儘管在函數啟動之前上下文已取消,但仍會發送心跳訊息。這是因為評估的順序是不可預測的,並且預設情況或心跳情況可能會在上下文情況之前輸入。
不正確的建議:func sendRegularHeartbeats(ctx context.Context) { for { // Primordial select: Check for context channel being ready only. select { case <-ctx.Done(): return default: } // Secondary select: Handle heartbeat logic. select { case <-ctx.Done(): return case <-time.After(1 * time.Second): sendHeartbeat() } } }一個建議的解決方案是加上「isContextclose」-檢查心跳狀況。然而,這不是一個可靠的解決方案,因為上下文和心跳通道都可以同時準備好讀取。
建議的解決方案:原始選擇
優先考慮上下文情況,我們可以引入一個原始的 select 語句來測試上下文通道是否準備就緒。只有當上下文通道沒有準備好時,才會執行第二個 select 語句。 不完美:雖然這種方法有效地優先考慮了上下文情況,但它可能仍然允許「足夠接近」的事件。例如,如果在上下文通道準備好之後不久心跳事件到達,則可以在進入上下文情況之前發送心跳。目前的Go語言實作還沒有完美的解決這個問題。以上是如何保證 Go 的 select 語句中上下文取消的優先權?的詳細內容。更多資訊請關注PHP中文網其他相關文章!