ホームページ >バックエンド開発 >Golang >Go でコンテキストのリークを防ぐために「defer cancel()」が重要なのはなぜですか?

Go でコンテキストのリークを防ぐために「defer cancel()」が重要なのはなぜですか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-11-17 19:13:02932ブラウズ

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

Go でのコンテキスト リーク: defer cancel() をスキップすることの影響

Go では、コンテキスト パッケージはキャンセルを並行処理に渡す方法を提供します。ルーティン。 context.WithTimeout 関数は、指定された期間が経過するとキャンセルされるタイムアウトを持つ新しいコンテキストを作成します。結果の 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() missing here
    return http.DefaultClient.Do(req)
}

defer cancel() ステートメントがないと、cancel 関数は呼び出されません。 WithTimeout によって作成された goroutine は無期限に存在し続けます。リクエストが完了した場合でも、ゴルーチンはプログラムが終了するまでメモリ内に残るため、これはメモリ リークです。

リークが発生すると過剰なメモリ消費につながる可能性があるため、go vet ツールはこのリークについて警告します。頻繁に発生します。慢性的なメモリ リークは、最終的にシステム パフォーマンスの問題を引き起こしたり、クラッシュを引き起こす可能性があります。

コンテキスト リークを回避するには、コンテキストが不要になったときに cancel 関数を呼び出すことが重要です。ベスト プラクティスは、次の変更コードに示すように、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)
}

このプラクティスに従うことで、ゴルーチンと関連リソースが確実に実行されます。使用後すぐに解放されるため、メモリ リークの可能性が最小限に抑えられ、システム パフォーマンスが最適化されます。

以上がGo でコンテキストのリークを防ぐために「defer cancel()」が重要なのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。