1
4

More than 5 years have passed since last update.

Go言語の並列処理 goroutineとchannel

Last updated at Posted at 2018-01-23

はじめに

Go言語と言えば、並列プログラミングということでgoroutine、channelに触れてみようと思います。

goroutine

goroutine は go 文で関数を実行すると起動できます。

goroutine.go
package main

import (
    "log"
    "time"
)

func f() {
    log.Println("goroutine")
}

func main() {
    go f()
    log.Println("main")
    time.Sleep(time.Second)
    log.Println("finish")
}

実行結果
2018/01/23 20:35:46 main
2018/01/23 20:35:46 goroutine
2018/01/23 20:35:47 finish

go f()が実行されてから、すぐにlog.Println("main")が実行されていることが分かると思います。
こんなに簡単に並列処理ができるのはすごいですね...(まだ、使いこなせる気はしないですが)
goroutineは並列処理している関数が終了した時に終了されます。

channel

channel は goroutine 間での変数の受け渡しができます。
<- (オペレータ)を使って、値の受け渡しをするのですが、どういう型の値を扱うのか宣言できたりもします。
また、値の受け渡しがされてから、値が届くまでブロックしてくれるので、待ち時間を設ける必要がありません。

channel.go
package main

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

func f(c chan string) {
    time.Sleep(10 * time.Second)
    c <- "well come"
}

func main() {
    c := make(chan string)
    log.Print("started")
    go f(c)
    w1 := <-c//go f(c)実行後、即座に呼ばれていない
    log.Print("finished")
    fmt.Println(w1)
}

実行結果
2018/01/23 21:52:47 started
2018/01/23 21:52:57 finished
well come

go f(c)の実行後、w1 := <-cが即座に呼ばれていないことがわかると思います。
これらをより上手く使うために、selectといった機能があります。

select文

「select」文は、複数のチャネルを待機する場合に使用します。構文は「switch」文と同じく「case」を使用します。
「case」に指定したチャネルのうち、どれかを受信するまで待機します。

select.go
package main

import (
    "fmt"
    "log"
)

func printa(a chan string) {
    a <- "a"
}

func printb(b chan string) {
    b <- "b"
}

func printc(c chan string) {
    c <- "c"
}

func main() {
    a := make(chan string)
    b := make(chan string)
    c := make(chan string)
    log.Print("started")
    go printa(a)
    go printb(b)
    go printc(c)
    for i := 0; i < 3; i++ {
        select {
        case msga := <-a:
            fmt.Println("finished", msga)
        case msgb := <-b:
            fmt.Println("finished", msgb)
        case msgc := <-c:
            fmt.Println("finished", msgc)

        }
    }

    log.Print("finished")

}

実行結果
2018/01/23 21:50:33 started
finished c
finished a
finished b
2018/01/23 21:50:33 finished

1
4
0

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
1
4