ホームページ > バックエンド開発 > Golang > Go ルーチンが終了するのを適切に待つにはどうすればよいですか?

Go ルーチンが終了するのを適切に待つにはどうすればよいですか?

Barbara Streisand
リリース: 2024-12-07 16:34:15
オリジナル
235 人が閲覧しました

How to Gracefully Wait for Go Routines to Finish?

Go ルーチンの終了を正常に待つ方法

Go では、同時実行はゴルーチンによって実現されます。ゴルーチンは、同時に実行される軽量のスレッドです。メインルーチン。すべてのゴルーチンがタスクを完了する前にプログラムが終了しないようにするには、それらが完了するまで適切に待つことが重要です。

チャネルを使用して完了を通知する

ゴルーチンを待機する一般的なアプローチの 1 つは、ブール チャネルを使用することです。 goroutine がタスクを完了すると、true 値をチャネルに送信し、メイン ルーチンはチャネルから受信してその値を待ちます。

func do_stuff(done chan bool) {
    fmt.Println("Doing stuff")
    done <- true
}

func main() {
    fmt.Println("Main")
    done := make(chan bool)
    go do_stuff(done)
    <-done
}
ログイン後にコピー

なぜ <-done は機能するのでしょうか?

<-done はブロッキング受信操作です。これは、値が完了チャネルに送信されるまでメイン ルーチンが待機することを意味します。 do_stuff ゴルーチンは終了時に明示的に true 値をチャネルに送信するため、メイン ルーチンはそれを受け取り、実行を続行します。

最後の行のコメントを解除するとどうなりますか?

最後の行のコメントを解除すると、チャネルが空で他のゴルーチンが値を送信していないため、デッドロック エラーが発生します。したがって、メイン ルーチンは値の受信を無限に待機することになり、デッドロックが発生します。

同期パッケージを使用した代替アプローチ

より複雑な同時実行シナリオの場合、同期パッケージは便利な同期メカニズムを提供します。たとえば、一連の長時間実行関数を並列化する必要がある場合、次のコード スニペットは sync.WaitGroup タイプの使用方法を示しています。

package main

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

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            longOp()
            wg.Done()
        }()
    }

    // will wait until wg.Done is called 10 times
    // since we made wg.Add(1) call 10 times
    wg.Wait()
}

func longOp() {
    time.Sleep(time.Second * 2)
    fmt.Println("long op done")
}
ログイン後にコピー

この例では、WaitGroup はメイン ルーチンを確実に実行します。すべてのゴルーチンが wg.Done を呼び出すまで終了しません。

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

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