mainからgoroutineの終了を通知する

下で書いたやり方でもできるけど同じことはcontext.Contextを用いて行った方が筋が良いらしい

main関数にあるgoroutineが終了したことを通知するにはsync.WaitGroup()を使えば良いです。 しかし, maiinからあるgoroutineに終了通知をするには同様にはできないため, 別の方法を使う必要があります。doneという終了通知チャンネルを 用意してそれをつかうことで実現できます。

package main

import (
    "fmt"
    "time"
)

func protocol(ch chan int, done chan struct{}) {
    for {
        select {
        case a := <-ch:
            // aをパケットだと思って処理
            fmt.Println(a)
        case <-done:
            fmt.Println("done")
            return
        default:
            continue
        }
    }
}

func main() {
    ch := make(chan int, 10)
    done := make(chan struct{})

    // 通信開始
    go protocol(ch, done)

    for i := 0; i < 7; i++ {
        ch <- i // パケットがネットワークを通じて届く
        time.Sleep(time.Second)
    }

    // 通信終了
    close(done)
}

select 文の中身がa := <- ch<-doneで入れ替わらないようにしましょう。