ゴルーチンの実行順序について
ゴルーチンベースのプログラムでは、ゴルーチンの実行順序が予測できない場合があります。これは、ゴルーチンが同時に実行され、いつどの順序でタスクを完了するかという保証がないためです。
次のコード スニペットを考えてみましょう。
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 サイトの他の関連記事を参照してください。