首頁  >  文章  >  後端開發  >  為什麼你應該總是延遲取消 Go 中的上下文?

為什麼你應該總是延遲取消 Go 中的上下文?

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-11-14 10:00:03116瀏覽

Why Should You Always Defer Canceling a Context in Go?

取消 Context 失敗:後果和解決方法

在 Go 的並發環境中,Context 控制著 goroutine 的生命週期和行為。它提供了一種傳播截止日期、取消訊號和其他重要資訊的方法。但是,未能正確取消 Context 可能會導致不良後果。

考慮以下程式碼片段:

func Call(ctx context.Context, payload Payload) (Response, error) {
    req, err := http.NewRequest(...) // Some code that creates request from payload
    ctx, cancel = context.WithTimeout(ctx, time.Duration(3) * time.Second)
    defer cancel()
    return http.DefaultClient.Do(req)
}

這裡建立了一個新的 Context,超時時間為 3 秒。如果沒有 defer cancel() 語句,則函數會在不明確取消 Context 的情況下傳回。這會觸發 go vet 發出警告:

context 傳回的取消函數。 WithTimeout 應該被調用,而不是丟棄,以避免上下文洩漏

上下文洩漏及其影響

那麼,如果Context沒有被取消會發生什麼?這種遺漏會在系統中造成「洩漏」。負責處理 Context 取消的 goroutine 無限期地保持活動狀態,即使它沒有任何作用。如果這種浪費的資源在程式中頻繁發生,可能會導致顯著的記憶體開銷。

最佳實踐:立即取消

為了避免上下文洩漏,最好的做法是立即推遲取消( )在使用 WithCancel() 或 WithTimeout() 創建新的 Context 後。這確保了函數在返回後立即執行取消邏輯,無論是否有任何早期返回或異常。

總而言之,忽略取消 Context 可能會導致 goroutine 無限期運行,從而導致記憶體洩漏。為了防止這種情況,請始終在使用 WithCancel() 或 WithTimeout() 建立新上下文後立即延遲取消函數。

以上是為什麼你應該總是延遲取消 Go 中的上下文?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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