channelに値を送信する関数と、
channelから値を受信して処理をする関数を作成し、
sync.WaitGroupを使って並行処理を行います。
func producer(c chan int, i int) {
c <- i * 3
}
func consumer(c chan int, wg *sync.WaitGroup) {
for v := range c {
func() { // 無名関数化することで、処理(この例ではfmt.Println(v, *wg))に問題があってもDoneが呼ばれるようになり、止まるのを防ぐ
defer wg.Done() // 無名関数内の処理が終わったらwgが管理する個数を1つ減らす
fmt.Println(v, *wg) // *wgで、wgの個数が減少する様子を確認できる
}()
}
fmt.Println("*************") // wg.Wait()完了後にclose()し、時間待ちすることで出力される
}
func main() {
var wg sync.WaitGroup
c := make(chan int, 10)
for i := 0; i < 10; i++ {
wg.Add(1) // forループの個数分、wgが管理する個数を追加する
go producer(c, i) // 擬似的に複数処理を生成する
}
go consumer(c, &wg)
wg.Wait() // consumer内で、全てDoneされるまで待つ
close(c) // closeすることで、consumer内のchannelのfor rangeループが終点を認識し、ループから抜けることができる
time.Sleep(1 * time.Millisecond) // consumer内のchannelのfor rangeループから抜けたことを確認するために、時間待ちをする必要がある
fmt.Println("Done")
}
いくつかの処理から並行して値を受け取り、
channelを通して出力する処理を行なっています。