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 サイトの他の関連記事を参照してください。