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