selectでチャネルに応じた処理を行う。
複数のチャネルを使って複数のゴルーチンとやり取りをするとき、受信したチャネルによって処理を分岐させたい場合がある。その場合、selectを使うことでチャネルごとの処理を書くことができる。
イメージ
コードとして表現する。string型のチャネルを2つ作成し、goroutine1関数とgorutine2関数に渡してゴルーチンで実行する。
func main() {
c1 := make(chan string)
c2 := make(chan string)
go goroutine1(c1)
go goroutine2(c2)
goroutine1関数の中では、for文で無限ループを作り「ch <- "packet from 1"」と書いて、チャネルに文字列「packet from 1」を送信する。これは、ネットワークから来るパケットを取り続けてチャネルに送り続けるイメージ。また、次に来るパケットまで時間がかかるという想定で、Sleepで1秒待つ処理も書いておく。
func goroutine1(ch chan string) {
for {
ch <- "packet from 1"
time.Sleep(1 * time.Second)
}
}
goroutine2関数も同様に書く。送信する文字列は「packet from 2」と変えておく。
func goroutine2(ch chan string) {
for {
ch <- "packet from 2"
time.Sleep(1 * time.Second)
}
}
main関数で受信するには、for文で次のようにselectを使う。selectの中にcaseでc1が来た場合とc2が来た場合で分ける。
for {
select {
case msg1 := <- c1:
fmt.Println(msg1)
case nsg2 := <- c2:
fmt.Println(msg2)
}
}
全体のコードをつなげると以下のようになる。
func goroutine1(ch chan string) {
for {
ch <- "packet from 1"
time.Sleep(1 * time.Second)
}
}
func goroutine2(ch chan string) {
for {
ch <- "packet from 2"
time.Sleep(1 * time.Second)
}
}
func main() {
c1 := make(chan string)
c2 := make(chan string)
go goroutine1(c1)
go goroutine2(c2)
for {
select {
case msg1 := <- c1:
fmt.Println(msg1)
case msg2 := <- c2:
fmt.Println(msg2)
}
}
//以下のように出力される
packet from 1
packet from 2
packet from 2
packet from 1
packet from 1
packet from 2
以下略
goroutine1 と goroutine2 が並行して動作し、それぞれのチャネルを介してメッセージを main 関数に送信し、main 関数はそれを受信して表示するという流れが成立する。
具体的なイメージとしては、goroutine1 が「パケット1」を1秒ごとに生成してパイプに流し込み、main 関数がそのパイプからデータを受け取って表示し、goroutine2 も同様に「パケット2」を生成し、別のパイプに流し込むイメージ。
学習に使用した教材
・『入門】Golang基礎入門 + 各種ライブラリ + 簡単なTodoWebアプリケーション開発(Go言語)』M.A EduTech
https://www.udemy.com/course/golang-webgosql/?utm_medium=udemyads&utm_source=bene-msa&utm_campaign=responsive&utm_content=top-1&utm_term=general&msclkid=81e2f24a32cc185d275d953d60760226&couponCode=NEWYEARCAREERJP
・『シリコンバレー一流プログラマーが教える Goプロフェッショナル大全』酒井 潤 (著)
https://www.amazon.co.jp/%E3%82%B7%E3%83%AA%E3%82%B3%E3%83%B3%E3%83%90%E3%83%AC%E3%83%BC%E4%B8%80%E6%B5%81%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC%E3%81%8C%E6%95%99%E3%81%88%E3%82%8B-Go%E3%83%97%E3%83%AD%E3%83%95%E3%82%A7%E3%83%83%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%AB%E5%A4%A7%E5%85%A8-%E9%85%92%E4%BA%95-%E6%BD%A4/dp/4046070897