ホームページ >バックエンド開発 >Golang >Go でゴルーチンの実行順序を制御するにはどうすればよいですか?

Go でゴルーチンの実行順序を制御するにはどうすればよいですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-12-12 16:54:10866ブラウズ

How Can I Control the Execution Order of Goroutines in Go?

ゴルーチンの実行順序について

ゴルーチンベースのプログラムでは、ゴルーチンの実行順序が予測できない場合があります。これは、ゴルーチンが同時に実行され、いつどの順序でタスクを完了するかという保証がないためです。

次のコード スニペットを考えてみましょう。

func sum(a []int, c chan int) {
    fmt.Println("summing: ", a)
    total := 0
    for _, v := range a {
        total += v
    }
    c <- total  // send total to c
}

func main() {
    c := make(chan int)

    go sum([]int{1,2,3}, c)
    go sum([]int{4,5,6}, c)

    x := <-c
    fmt.Println(x)
    x = <-c
    fmt.Println(x)
}

この例では、2 つのゴルーチンが存在します。 2 つの整数スライスの合計を計算するために起動されます。ただし、それらが実行され、その結果が出力される順序は決定的ではありません。出力は次のようになります。

summing:  [4 5 6]
15
summing:  [1 2 3]
6

または

summing:  [1 2 3]
6
summing:  [4 5 6]
15

ゴルーチンの実行順序を同期するには、さまざまなアプローチを使用できます。

使用チャネルのブロック:

チャネルのブロック特性を利用することで、次のゴルーチンに進む前に、メインのゴルーチンが各ゴルーチンの完了を待機するように強制できます。例:

func main() {

    c := make(chan int)

    go sum([]int{1, 2, 3}, c)

    // Blocks until a value is received
    x := <-c
    fmt.Println(x)

    // Execute the next goroutine
    go sum([]int{4, 5, 6}, c)

    x = <-c
    fmt.Println(x)
}

待機グループの使用:

もう 1 つの一般的な同期手法には、待機グループの使用が含まれます。待機グループは、まだ実行中のゴルーチンの数を追跡し、それらがすべて完了するまで待ってから次に進みます。上記の例で待機グループを使用する方法は次のとおりです。

func sum(a []int, c chan int, wg *sync.WaitGroup) {
    defer wg.Done()
    fmt.Println("summing: ", a)
    total := 0
    for _, v := range a {
        total += v
    }
    c <- total // send total to c
}

func main() {

    c := make(chan int)
    wg := new(sync.WaitGroup)

    // Increment the wait group
    wg.Add(1)
    // Launch the first goroutine
    go sum([]int{1, 2, 3}, c, wg)

    // Wait for the first goroutine to complete
    wg.Wait()

    // Increment the wait group again
    wg.Add(1)
    // Launch the second goroutine
    go sum([]int{4, 5, 6}, c, wg)

    // Wait for the second goroutine to complete
    wg.Wait()

    // Close the channel to indicate that no more values will be sent
    close(c)

    // Range over the channel to receive the results
    for theSum := range c {
        x := theSum
        fmt.Println(x)
    }

}

同期テクニックをコードに組み込むことで、ゴルーチンの実行順序をより詳細に制御できるようになり、ゴルーチンが確実にタスクを完了できるようになります。希望のシーケンス。

以上がGo でゴルーチンの実行順序を制御するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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