同時プログラミング スキル: Go WaitGroup の高度な使用法

王林
リリース: 2023-09-28 21:52:45
オリジナル
912 人が閲覧しました

并发编程技巧:Go WaitGroup的高级用法

コンカレント プログラミング スキル: Go WaitGroup の高度な使用法

コンカレント プログラミングでは、複数の同時タスクの実行を調整および管理することが重要なタスクです。 Go 言語は、非常に実用的な同時実行プリミティブである WaitGroup を提供します。これは、同時実行制御をエレガントに実装するのに役立ちます。この記事では、WaitGroup の基本的な使用法を紹介し、読者がそれをよりよく理解して適用できるように、具体的なコード例を使用してその高度な使用法に焦点を当てます。

WaitGroup は Go 言語に組み込まれた同時実行プリミティブで、同時タスクの完了を待つのに役立ちます。これには、Add、Done、Wait の 3 つのメソッドが用意されています。 Add メソッドは待機中のタスクの数を設定するために使用され、Done メソッドは待機中のタスクの数を減らすために使用され、Wait メソッドは待機中のすべてのタスクが完了するまで現在のコルーチンをブロックするために使用されます。

以下は、WaitGroup の基本的な使用法を示す簡単な例です。

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(num int) {
            defer wg.Done()

            time.Sleep(time.Second)
            fmt.Println("Task", num, "done")
        }(i)
    }

    wg.Wait()
    fmt.Println("All tasks done")
}
ログイン後にコピー

上記のコードでは、WaitGroup オブジェクト wg を作成し、ループを通じて 5 つの同時タスクを作成します。各タスクの実行中に、Add メソッドを使用して待機中のタスクの数を増やし、タスクの終了時に Done メソッドを使用して待機中のタスクの数を減らします。最後に、Wait メソッドを呼び出して、待機中のタスクがすべて完了するまでメイン コルーチンをブロックします。

WaitGroup では、基本的な使用法に加えて、同時タスクの実行をより柔軟に制御できる高度な使用法も提供しています。以下では、一般的に使用される高度な使用法をいくつか詳しく紹介します。

  1. 一連のタスクを実行し、同時実行の最大数を設定する

一連のタスクを同時に実行する必要があるが、最大数を制限したい場合同時実行性を実現するには、バッファリングされたチャネルの組み合わせ WaitGroup を使用します。以下のコードは、一連のタスクを同時に実行する方法を示していますが、同時に実行できるタスクは 3 つまでです:

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup
    maxConcurrency := 3
    tasks := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

    sem := make(chan struct{}, maxConcurrency)

    for _, task := range tasks {
        wg.Add(1)
        sem <- struct{}{} // 获取令牌,控制最大并发数

        go func(num int) {
            defer wg.Done()

            time.Sleep(time.Second)
            fmt.Println("Task", num, "done")

            <-sem // 释放令牌,允许新的任务执行
        }(task)
    }

    wg.Wait()
    fmt.Println("All tasks done")
}
ログイン後にコピー

上記のコードでは、バッファリングされたチャネル sem を作成し、そのサイズを次のように設定します。同時実行の最大数。各タスクを開始する前に、sem <- struct{}{} ステートメントを通じてトークンを取得します。タスクが完了したら、<-sem ステートメントを使用してトークンを解放します。トークンの取得と解放を制御することで、同時実行の最大数を制限できます。

  1. タイムアウトによる同時タスクの実行の制御

同時タスクの実行時間を制御し、タイムアウトになったらタスクの実行を終了したい場合があります。バッファリングされたチャネルとタイマーを使用すると、この機能を簡単に実装できます。次のコードは、同時タスクのタイムアウトを 3 秒に設定する方法を示しています。

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup
    tasks := []int{1, 2, 3, 4, 5, 6, 7}

    timeout := 3 * time.Second
    done := make(chan struct{})

    for _, task := range tasks {
        wg.Add(1)

        go func(num int) {
            defer wg.Done()

            // 模拟任务执行时间不定
            time.Sleep(time.Duration(num) * time.Second)
            fmt.Println("Task", num, "done")

            // 判断任务是否超时
            select {
            case <-done:
                // 任务在超时前完成,正常退出
                return
            default:
                // 任务超时,向通道发送信号
                close(done)
            }
        }(task)
    }



    wg.Wait()
    fmt.Println("All tasks done")
}
ログイン後にコピー

上記のコードでは、done チャネルを作成し、タスクの実行中にチャネルが閉じられているかどうかを確認して、タスクが実行されているかどうかを判断します。タイムアウト。タスクが完了すると、close(done) ステートメントを使用して、done チャネルにシグナルを送信し、タスクがタイムアウトしたことを示します。さまざまな状況に対処するには、select ステートメントを通じてさまざまなブランチを選択します。

上記のサンプル コードを通じて、WaitGroup の高度な使用法が実際の同時プログラミングで非常に実用的であることがわかります。これらのテクニックを習得すると、同時タスクの実行をより適切に制御し、コードのパフォーマンスと保守性を向上させることができます。この記事の紹介とサンプルコードを通じて、WaitGroup の使い方を深く理解し、実際のプロジェクトに適用していただければ幸いです。

以上が同時プログラミング スキル: Go WaitGroup の高度な使用法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート