Goroutines

Goroutines #

// <em>ゴルーチン</em>は軽量なスレッドである。

package main

import (
	"fmt"
	"time"
)

func f(from string) {
	for i := 0; i < 3; i++ {
		fmt.Println(from, ":", i)
	}
}

func main() {

	// `f(s)` という関数を呼ぶとしよう。
	// 普通にこのように書けばよく、関数は同期的に実行される。
	f("direct")

	// `go f(s)` と書くと、この関数をゴルーチンの中で実行する。
	// こうすると、新たなゴルーチンが呼び出し側と平行に実行される。
	go f("goroutine")

	// 無名関数のゴルーチンを起動することもできる。
	go func(msg string) {
		fmt.Println(msg)
	}("going")

	// 2つの関数呼び出しは、別々のゴルーチンにおいて非同期的に実行されている。
	// そのため処理はここまで抜けてくる。
	// ここで処理が終わるのを待つ([WaitGroup](waitgroups) を使うとより確実だ)。
	time.Sleep(time.Second)
	fmt.Println("done")
}
# このプログラムを実行すると、ブロックする呼び出しの出力がまず表示され、
# その後2つのゴルーチンの出力が入り混じって表示される。
# こうなるのは Go のランタイムがゴルーチンを平行に実行しているためである。
$ go run goroutines.go
direct : 0
direct : 1
direct : 2
goroutine : 0
going
goroutine : 1
goroutine : 2
done

# 次は、Go における並行プログラミングをする際にゴルーチンとしばしば一緒に使われるチャネルを紹介する。