LoginSignup
3
3

More than 5 years have passed since last update.

Golang Goの並列処理を学ぶ(select)

Posted at

Golang goの並列処理を学ぶ の続き

1秒待つ、2秒待つ、3秒待つ、という処理は順番にやると6秒かかります。それを一気にまとめて3秒でやってしまおう、というコード。

1秒待つ処理が終わったら 1
2秒待つ処理が終わったら 2
3秒待つ処理が終わったら 3
を送信して、 "finished (数字)"というのを出力してやることにします。

ここを参考にしてみました。

package main

import (
    "fmt"
    "log"
    "time"
)

func wait1(c chan string) {
    time.Sleep(1 * time.Second)
    c <- "1"
}

func wait2(c chan string) {
    time.Sleep(2 * time.Second)
    c <- "2"
}

func wait3(c chan string) {
    time.Sleep(3 * time.Second)
    c <- "3"
}

func main() {
    c := make(chan string)
    log.Print("started")
    go wait1(c)
    go wait2(c)
    go wait3(c)
    for i := 0; i < 3; i++ {
        select {
        case msg1 := <-c:
            fmt.Println("finished", msg1)
        case msg2 := <-c:
            fmt.Println("finished", msg2)
        case msg3 := <-c:
            fmt.Println("finished", msg3)

        }
    }

    log.Print("finished")

}

きっちり三秒で終わりました。

2015/11/25 10:57:44 started
finished 1
finished 2
finished 3
2015/11/25 10:57:47 finished

でもこうすると

func main() {
    c := make(chan string)
    log.Print("started")
    go wait1(c)
    go wait2(c)
    go wait3(c)
    for {
        select {
        case msg1 := <-c:
            fmt.Println("finished", msg1)
        case msg2 := <-c:
            fmt.Println("finished", msg2)
        case msg3 := <-c:
            fmt.Println("finished", msg3)

        }
    }
2015/11/25 11:08:37 started
finished 1
finished 2
finished 3
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [select]:
main.main()
        /home/test.go:31 +0x7a7
exit status 2

エラーが出てしまいます。
なんでForループを使わないとエラーが出るのかはよくわかりません。

for i := 0; i < 10; i++ {

のように、チャンネルより多い数を指定してもエラーが出るみたいですね。
少ない数だとその数だけしか処理してくれないみたいです。

3
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3