ホームページ > バックエンド開発 > Golang > メイン出口の前に Go ルーチンを確実に完了させるにはどうすればよいですか?

メイン出口の前に Go ルーチンを確実に完了させるにはどうすればよいですか?

DDD
リリース: 2024-12-09 16:33:14
オリジナル
802 人が閲覧しました

How to Ensure Go Routines Complete Before Main Exits?

Go ルーチンの完了を待機しています

Go では、ゴルーチンを使用して同時タスクを実行するのが一般的です。メイン プログラムが終了する前にすべてのゴルーチンが終了するのを確実に待機するようにするには、適切な同期メカニズムを実装することが重要です。

質問で述べたように、1 つのアプローチには、ブール チャネル (done) の使用が含まれます。

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 は、チャネル受信をブロックします。チャネル上で値が送信されるまで待機します。提供されたコードでは、タスクの完了時に do_stuff がチャネル上で true を送信し、main の <-done 操作が成功します。

最後の行のコメント解除によるデッドロック:

メインの最後の行のコメントを解除するとデッドロックが発生します:

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

この 2 番目<-done 操作は、値を送信するゴルーチンを使用せずに、空のチャネルからの読み取りを試みます。その結果、プログラムはデッドロックでハングします。

同期パッケージを使用した代替同期方法:

より複雑なシナリオの場合、同期パッケージは代替同期プリミティブを提供します。提供されたコードでは、sync.WaitGroup は goroutine の完了を効果的に追跡できます。

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 (10 goroutines finish)
    wg.Wait()
}

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

sync.WaitGroup を使用すると、main はプログラムを終了する前に 10 個の goroutine がすべて完了するまで待機します。

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

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