首頁 > 後端開發 > Golang > 為什麼「defer cancel()」對於防止 Go 中的上下文洩漏至關重要?

為什麼「defer cancel()」對於防止 Go 中的上下文洩漏至關重要?

Mary-Kate Olsen
發布: 2024-11-17 19:13:02
原創
903 人瀏覽過

Why is `defer cancel()` crucial to prevent context leaks in Go?

Go 中的上下文洩漏:跳過defer cancel() 的影響

在Go 中,context 套件提供了一種將取消傳遞給並發的方法例程。 context.WithTimeout 函數會建立一個帶有逾時的新上下文,該逾時將在指定的持續時間後取消。如果不呼叫產生的取消函數,則會發生上下文洩漏。

在提供的程式碼片段中:

func Call(ctx context.Context, payload Payload) (Response, error) {
    req, err := http.NewRequest(...)
    ctx, cancel = context.WithTimeout(ctx, time.Duration(3) * time.Second)
    //defer cancel() missing here
    return http.DefaultClient.Do(req)
}
登入後複製

如果沒有 defer cancel() 語句,則不會呼叫 cancel 函數並且WithTimeout創建的goroutine會無限期地繼續存在。這是記憶體洩漏,因為即使請求已完成,goroutine 也會保留在記憶體中直到程式退出。

go vet 工具會警告此洩漏,因為如果洩漏,可能會導致記憶體消耗過多經常發生。慢性記憶體洩漏最終會導致系統效能問題甚至崩潰。

為了避免上下文洩漏,當不再需要上下文時呼叫取消函數至關重要。最佳實踐是在呼叫WithCancel 或WithTimeout 後立即使用defer cancel() 語句,如以下修改後的程式碼所示:

func Call(ctx context.Context, payload Payload) (Response, error) {
    req, err := http.NewRequest(...)
    ctx, cancel = context.WithTimeout(ctx, time.Duration(3) * time.Second)
    defer cancel() // Added defer cancel() to release resources
    return http.DefaultClient.Do(req)
}
登入後複製

透過遵循此實踐,您可以確保goroutine 和關聯資源使用後立即釋放,最大限度地減少記憶體洩漏的可能性並優化系統效能。

以上是為什麼「defer cancel()」對於防止 Go 中的上下文洩漏至關重要?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板