検索
ホームページバックエンド開発Golangマスター Go の同時実行性: コンテキストの伝播とキャンセルの秘密が明らかに

Master Go

Go の同時実行モデルは革新的ですが、複雑な同時操作の管理は難しい場合があります。ここで、コンテキストの伝播とキャンセルが登場します。これらの強力なツールを使用すると、複数のゴルーチン、さらにはネットワーク境界にまたがる、堅牢でキャンセル可能な操作を構築できます。

基本から始めましょう。コンテキスト パッケージは、期限、キャンセル シグナル、リクエスト スコープの値を API 境界を越えて、またプロセス間で伝達する方法を提供します。これは、長時間実行される操作を制御し、サービスを正常にシャットダウンするための秘密のソースです。

キャンセルにコンテキストを使用する簡単な例を次に示します。

func longRunningOperation(ctx context.Context) error {
    for {
        select {
        case 



<p>この例では、5 秒のタイムアウトを持つコンテキストを作成します。操作が時間内に完了しない場合、操作は自動的にキャンセルされます。</p>

<p>しかし、コンテキストはタイムアウトのためだけのものではありません。これを使用して、複数のゴルーチンにわたってキャンセル信号を伝播できます。これは、複雑なワークフローを管理するのに非常に役立ちます。</p>

<p>分散トランザクション システムを構築するシナリオを考えてみましょう。単一のトランザクションに複数のマイクロサービスが関与している可能性があり、いずれかの部分で障害が発生した場合にトランザクション全体がロールバックされるようにする必要があります。</p>

<p>コンテキストを使用してこれを構造化する方法は次のとおりです。<br>
</p>

<pre class="brush:php;toolbar:false">func performTransaction(ctx context.Context) error {
    // Start the transaction
    tx, err := db.BeginTx(ctx, nil)
    if err != nil {
        return err
    }
    defer tx.Rollback() // Will be no-op if tx.Commit() is called

    // Perform multiple operations
    if err := operation1(ctx); err != nil {
        return err
    }
    if err := operation2(ctx); err != nil {
        return err
    }
    if err := operation3(ctx); err != nil {
        return err
    }

    // If we've made it this far, commit the transaction
    return tx.Commit()
}

func operation1(ctx context.Context) error {
    // Make an HTTP request to another service
    req, err := http.NewRequestWithContext(ctx, "GET", "http://service1.example.com", nil)
    if err != nil {
        return err
    }
    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    // Process the response...
    return nil
}

この例では、コンテキストを使用して、データベース操作と HTTP リクエストの両方にキャンセルを伝達しています。コンテキストがいずれかの時点でキャンセルされると (タイムアウトまたは明示的なキャンセルにより)、すべての操作が終了し、リソースがクリーンアップされます。

しかし、キャンセルをさらに細かく制御する必要がある場合はどうすればよいでしょうか?そこでカスタム コンテキスト タイプが登場します。ドメイン固有のキャンセル シグナルを伝える独自のコンテキスト タイプを作成できます。

「優先度」値を含むカスタム コンテキストの例を次に示します。

type priorityKey struct{}

func WithPriority(ctx context.Context, priority int) context.Context {
    return context.WithValue(ctx, priorityKey{}, priority)
}

func GetPriority(ctx context.Context) (int, bool) {
    priority, ok := ctx.Value(priorityKey{}).(int)
    return priority, ok
}

func priorityAwareOperation(ctx context.Context) error {
    priority, ok := GetPriority(ctx)
    if !ok {
        priority = 0 // Default priority
    }

    // Use the priority to make decisions...
    switch priority {
    case 1:
        // High priority operation
    case 2:
        // Medium priority operation
    default:
        // Low priority operation
    }

    return nil
}

このカスタム コンテキストを使用すると、キャンセル信号とともに優先度情報を伝播できるため、同時操作をさらに細かく制御できるようになります。

ここで、正常なシャットダウンについて話しましょう。長時間実行されるサービスを構築する場合、シャットダウン信号を適切に処理して、操作がハングしたり、リソースがクリーンアップされないままにされたりしないようにすることが重要です。

コンテキストを使用して正常なシャットダウンを実装する方法は次のとおりです。

func main() {
    // Create a context that's cancelled when we receive an interrupt signal
    ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
    defer cancel()

    // Start our main service loop
    errChan := make(chan error, 1)
    go func() {
        errChan 



<p>この設定により、サービスが割り込み信号を受信したときに正常にシャットダウンできるようになり、リソースをクリーンアップして進行中の操作を終了する時間が与えられます。</p>

<p>Go のコンテキスト システムの最も強力な側面の 1 つは、ネットワーク境界を越えてキャンセルを伝播する機能です。これは、操作が複数のサービスにまたがる可能性がある分散システムを構築する場合に特に役立ちます。</p><p>これをマイクロサービス アーキテクチャで実装する方法の例を見てみましょう:<br>
</p>

<pre class="brush:php;toolbar:false">func longRunningOperation(ctx context.Context) error {
    for {
        select {
        case 



<p>この例では、クエリ パラメーターに基づいてタイムアウトを設定したコンテキストを作成しています。このコンテキストは、後続のすべての API 呼び出しを通じて伝播されます。タイムアウトに達すると、進行中のすべての操作がキャンセルされ、クライアントにエラーが返されます。</p>

<p>このパターンにより、クライアントが応答の待機を放棄した後も長時間継続する「暴走」操作が発生しないことが保証されます。これは、応答性が高く、リソース効率の高い分散システムを構築するための重要な部分です。</p>

<p>同時実行システムでのエラー処理は難しい場合がありますが、ここでもコンテキストが役に立ちます。コンテキストを使用することで、エラーが正しく伝播され、エラーが発生した場合でもリソースがクリーンアップされることを保証できます。</p>

<p>これは、同時操作でエラーを処理する方法の例です:<br>
</p>

<pre class="brush:php;toolbar:false">func performTransaction(ctx context.Context) error {
    // Start the transaction
    tx, err := db.BeginTx(ctx, nil)
    if err != nil {
        return err
    }
    defer tx.Rollback() // Will be no-op if tx.Commit() is called

    // Perform multiple operations
    if err := operation1(ctx); err != nil {
        return err
    }
    if err := operation2(ctx); err != nil {
        return err
    }
    if err := operation3(ctx); err != nil {
        return err
    }

    // If we've made it this far, commit the transaction
    return tx.Commit()
}

func operation1(ctx context.Context) error {
    // Make an HTTP request to another service
    req, err := http.NewRequestWithContext(ctx, "GET", "http://service1.example.com", nil)
    if err != nil {
        return err
    }
    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    // Process the response...
    return nil
}

この例では、チャネルを使用して、ゴルーチンからメイン関数にエラーを伝えています。キャンセルのコンテキストも確認しています。これにより、操作自体からのエラーとコンテキストからのキャンセルの両方を確実に処理できます。

コンテキストの見落とされがちな側面の 1 つは、リクエスト スコープの値を運ぶ能力です。これは、リクエスト ID、認証トークン、その他のメタデータなどを API 境界を越えて伝播する場合に非常に役立ちます。

これを使用する例を次に示します:

type priorityKey struct{}

func WithPriority(ctx context.Context, priority int) context.Context {
    return context.WithValue(ctx, priorityKey{}, priority)
}

func GetPriority(ctx context.Context) (int, bool) {
    priority, ok := ctx.Value(priorityKey{}).(int)
    return priority, ok
}

func priorityAwareOperation(ctx context.Context) error {
    priority, ok := GetPriority(ctx)
    if !ok {
        priority = 0 // Default priority
    }

    // Use the priority to make decisions...
    switch priority {
    case 1:
        // High priority operation
    case 2:
        // Medium priority operation
    default:
        // Low priority operation
    }

    return nil
}

この例では、ミドルウェアを使用してリクエスト ID をコンテキストに追加しています。このリクエスト ID は取得され、このコンテキストを受け取る後続のハンドラーまたは関数で使用できます。

最後に、コンテキストは強力なツールではありますが、特効薬ではないことに注意してください。コンテキストを過度に使用すると、理解や保守が困難なコードが作成される可能性があります。コンテキストを慎重に使用し、API を慎重に設計することが重要です。

コンテキストの主な用途は、期限、キャンセル信号、リクエストスコープの値を API 境界を越えて伝達することであることに注意してください。これは、オプションのパラメーターを関数に渡すための汎用メカニズムを意図したものではありません。

結論として、コンテキストの伝播とキャンセルを含む Go の同時実行モデルをマスターすることが、堅牢で効率的でスケーラブルなアプリケーションを構築する鍵となります。これらのツールを活用することで、複雑なワークフローを適切に処理し、リソースを効果的に管理し、変化する状況にインテリジェントに対応するシステムを構築できます。私たちが並行プログラミングで可能なことの限界を押し広げ続けるにつれて、これらのテクニックは私たちのツールボックスにおいてさらに重要なものになるでしょう。


私たちの作品

私たちの作品をぜひチェックしてください:

インベスターセントラル | スマートな暮らし | エポックとエコー | 不可解な謎 | ヒンドゥーヴァ | エリート開発者 | JS スクール


私たちは中程度です

Tech Koala Insights | エポックズ&エコーズワールド | インベスター・セントラル・メディア | 不可解な謎 中 | 科学とエポックミディアム | 現代ヒンドゥーヴァ

以上がマスター Go の同時実行性: コンテキストの伝播とキャンセルの秘密が明らかにの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

GolangとPythonの主な違いは、並行性モデル、タイプシステム、パフォーマンス、実行速度です。 1. GolangはCSPモデルを使用します。これは、同時タスクの高いタスクに適しています。 Pythonは、I/O集約型タスクに適したマルチスレッドとGILに依存しています。 2。Golangは静的なタイプで、Pythonは動的なタイプです。 3.ゴーランコンパイルされた言語実行速度は高速であり、Python解釈言語開発は高速です。

Golang vs. C:速度差の評価Golang vs. C:速度差の評価Apr 18, 2025 am 12:20 AM

Golangは通常Cよりも遅くなりますが、Golangはプログラミングと開発効率の同時により多くの利点があります。1)Golangのゴミ収集と並行性モデルにより、同時性の高いシナリオではうまく機能します。 2)Cは、手動のメモリ管理とハードウェアの最適化により、より高いパフォーマンスを取得しますが、開発の複雑さが高くなります。

Golang:クラウドコンピューティングとDevOpsのキー言語Golang:クラウドコンピューティングとDevOpsのキー言語Apr 18, 2025 am 12:18 AM

GolangはクラウドコンピューティングとDevOpsで広く使用されており、その利点はシンプルさ、効率性、および同時プログラミング機能にあります。 1)クラウドコンピューティングでは、GolangはGoroutineおよびチャネルメカニズムを介して同時リクエストを効率的に処理します。 2)DevOpsでは、Golangの高速コンピレーションとクロスプラットフォーム機能により、自動化ツールの最初の選択肢になります。

Golang and C:実行効率の理解Golang and C:実行効率の理解Apr 18, 2025 am 12:16 AM

GolangとCにはそれぞれ、パフォーマンス効率に独自の利点があります。 1)GolangはGoroutineおよびGarbage Collectionを通じて効率を向上させますが、一時停止時間を導入する場合があります。 2)Cは、手動のメモリ管理と最適化を通じて高性能を実現しますが、開発者はメモリリークやその他の問題に対処する必要があります。選択するときは、プロジェクトの要件とチームテクノロジースタックを考慮する必要があります。

Golang vs. Python:並行性とマルチスレッドGolang vs. Python:並行性とマルチスレッドApr 17, 2025 am 12:20 AM

Golangは高い並行性タスクにより適していますが、Pythonには柔軟性がより多くの利点があります。 1.Golangは、GoroutineとChannelを介して並行性を効率的に処理します。 2。Pythonは、GILの影響を受けるが、複数の並行性メソッドを提供するスレッドとAsyncioに依存しています。選択は、特定のニーズに基づいている必要があります。

GolangとC:パフォーマンスのトレードオフGolangとC:パフォーマンスのトレードオフApr 17, 2025 am 12:18 AM

GolangとCのパフォーマンスの違いは、主にメモリ管理、コンピレーションの最適化、ランタイム効率に反映されています。 1)Golangのゴミ収集メカニズムは便利ですが、パフォーマンスに影響を与える可能性があります。

Golang vs. Python:アプリケーションとユースケースGolang vs. Python:アプリケーションとユースケースApr 17, 2025 am 12:17 AM

seetgolangforhighperformance andconcurrency、ithyforbackendservicesandnetworkプログラミング、selectthonforrapiddevelopment、datascience、andmachinelearningduetoistsversitydextentextensextensentensiveLibraries。

Golang vs. Python:重要な違​​いと類似点Golang vs. Python:重要な違​​いと類似点Apr 17, 2025 am 12:15 AM

GolangとPythonにはそれぞれ独自の利点があります。Golangは高性能と同時プログラミングに適していますが、PythonはデータサイエンスとWeb開発に適しています。 Golangは同時性モデルと効率的なパフォーマンスで知られていますが、Pythonは簡潔な構文とリッチライブラリエコシステムで知られています。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)