rangeの無限ループとgoroutine【Go】
for rangeの対象が、無限ループによって生成(更新)される場合、
for rangeの処理も終わらないため、下に記述された処理が行われません。
c := make(chan int) go func() { defer close(c) var i int for { // 無限ループ c <- i time.Sleep(1 * time.Second) i++ } }() for v := range c { // 上記goroutineのforループが無限処理のため、このfor range以降の処理がブロックされてしまう fmt.Println(v) } fmt.Println("blablabla") // 処理されない
for rangeを囲む新たなgoroutineを作成し、並行処理の対象にします。
これにより、そのgoroutineの処理の終了を待たずに、下に続く処理が開始されます。
c := make(chan int) var wg sync.WaitGroup go func() { var i int for { // 無限ループ wg.Add(1) c <- i time.Sleep(1 * time.Second) i++ } }() go func() { // 新たなgoroutineを作り、並行処理の対象とする for v := range c { defer wg.Done() fmt.Println(v) } }() fmt.Println("blablabla") // 上記処理がgoroutine化されたため、ブロックされなくなり処理される wg.Wait() // Addした分、Doneされたらmain関数を終了(producerが無限ループのため、終了しない)
起き得るケースとして、for rangeを含むメソッドや関数などを呼び出した後に
処理を追加したものの、処理が実行されない、ということがあるかと思います。
そのような際は事実を確認の上、応急処置として、for rangeのgoroutine化を試してみると良いでしょう。