for - select
複数のゴルーチンからの、チャネルを介した値受け渡しを実現させるための構文
selectを使用することにより対象のチャネルからピンポイントで値を受け渡せる。
Code
// ある数以上の素数を、1つ求める関数
func primeRoutine(targetLine int, primeChan chan int) {
fmt.Printf("%d Line Target Goroutine Wake UP \n", targetLine)
i := 0
for {
// 値のインクリメント
i++
// 素数チェック
if checkPrime(i) && targetLine < i {
fmt.Printf("%d Line Target Goroutine Shut Down \n", targetLine)
// チャネルにデータ送信
primeChan <- i
return
}
}
}
// メイン関数
func main() {
// 求める素数の基準値
targetLine1 := 100000
targetLine2 := 150000
targetLine3 := 200000
targetLine4 := 250000
targetLine5 := 300000
// チャネルの作成
primeChan1 := make(chan int)
primeChan2 := make(chan int)
primeChan3 := make(chan int)
primeChan4 := make(chan int)
primeChan5 := make(chan int)
// 複数のGoroutineを起動して、素数を求める
go primeRoutine(targetLine1, primeChan1)
go primeRoutine(targetLine2, primeChan2)
go primeRoutine(targetLine3, primeChan3)
go primeRoutine(targetLine4, primeChan4)
go primeRoutine(targetLine5, primeChan5)
loop:
// Goroutineからの返答を、selectを使って待ち受け
for {
select {
case primeResult1 := <-primeChan1:
fmt.Printf("Answer1 : %d \n", primeResult1)
case primeResult2 := <-primeChan2:
fmt.Printf("Answer2 : %d \n", primeResult2)
case primeResult3 := <-primeChan3:
fmt.Printf("Answer3 : %d \n", primeResult3)
case primeResult4 := <-primeChan4:
fmt.Printf("Answer4 : %d \n", primeResult4)
case primeResult5 := <-primeChan5:
fmt.Printf("Answer5 : %d \n", primeResult5)
// 5つ目を受信したら、forループを抜ける
break loop
default:
}
}
}
Output Sample
~ $ go build -o main main.go
~ $ ./main
100000 Line Target Goroutine Wake UP
200000 Line Target Goroutine Wake UP
150000 Line Target Goroutine Wake UP
250000 Line Target Goroutine Wake UP
300000 Line Target Goroutine Wake UP
100000 Line Target Goroutine Shut Down
Answer1 : 100003
150000 Line Target Goroutine Shut Down
Answer2 : 150001
200000 Line Target Goroutine Shut Down
Answer3 : 200003
250000 Line Target Goroutine Shut Down
Answer4 : 250007
300000 Line Target Goroutine Shut Down
Answer5 : 300007
GitHub