ゴルーチン


Go言語の並列処理

並列処理とは、プログラムで複数の処理を同時に実行することを言い、「マルチタスク」「マルチスレッド」などとも呼ばれています。Go言語では、これを実現するための「ゴルーチン」という仕組みが用意され、Go言語の代表的な機能の1つです。「ゴルーチン」は、独立して動作する実行単位であり、OSが管理するスレッドに割り当てられて動作します。 「ゴルーチン」として並列実行させたい処理は、関数として実装します。関数は、「ゴルーチン」だからと言って特別な実装は必要ありません。

ゴルーチンを使用した実装方法

関数を「ゴルーチン」として使用するには、関数の呼び出し時に先頭に「go」を付けるだけです。

// ゴルーチン呼び出しの書式
go 関数の呼び出し

上記の様に関数を呼び出すと、呼び出し元とは別の実行単位で動作を開始します。呼び出された関数が終了すると、その「ゴルーチン」も同時に終了します。特別な前処理・後処理は一切ありません。 一方、呼び出し側では、通常の関数と異なる点があります。それは、「ゴルーチン」として呼び出した関数の終了は待たないことです。そのため、呼び出した関数が返す戻り値を受け取ることはできません。 また、mainから開始している親となる処理が終了すれば、いくら他に「ゴルーチン」が動いていても、すべて中断して終了します。 ゴルーチンを使用したコード例は次の通り。

package main

import (
	"fmt"
	"time"
)

func main() {
	fmt.Println("main start.")

	fmt.Println("普通に関数を呼び出す")
	serialno()

	fmt.Println("ゴルーチンとして呼び出す")
	go serialno()

	// ゴルーチン呼び出し後、sleepする
	time.Sleep(1 * time.Second)

	fmt.Println("main end.")
}

func serialno() {
	for i := 0; i < 5; i++ {
		fmt.Println(i)
		// 1秒間sleepする
		time.Sleep(1 * time.Second)
	}
}

これを実行すると、次の結果が表示されます。(実行状況によっては、多少異なります)

main start.
普通に関数を呼び出す
0
1
2
3
4
ゴルーチンとして呼び出す
0
1
main end.

「ゴルーチン」として呼び出した場合は、シリアルナンバーの表示が中断されていることが分かります。

「ゴルーチン」と呼び出し元の間で、処理結果の連携などは、別途「チャネル」という機能を利用します。