goroutine とは
- Go 言語の主たる言語機能のひとつとして goroutine がある。
goroutine とは何か
goroutine を使ったコード例
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
package main
import (
"fmt"
"time"
)
func main() {
go func(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}("world")
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println("hello")
}
}
goroutine の特徴
- 軽量スレッドであり、いわゆるプロセス、スレッドよりも省リソース。
- スレッドは 1〜2 MB の初期スタックメモリを必要とするらしい。goroutine は 2 KB 程度。起動が速い。
- スレッドは CPU のコアにマッピングされるが、goroutine は OS のスレッドにマッピングされる。
- スレッドへの CPU 処理時間割当のスケジューリングは OS の仕事。
- goroutine への CPU 処理時間割当のスケジューリングは Go runtime の仕事。
- つまり M:N モデル (OS のスレッド M 個に対し、goroutine は N 個)。
余談: スレッドの実行モデルの種類
- N:1
- 1 個の OS スレッドの上で N 個のユーザー空間スレッドが動く
- コンテキストスイッチが速いがマルチコアの恩恵を受けられない
- 1:1
- 1 個の OS スレッドの上で 1 個のユーザー空間スレッドが動く
- コンテキストスイッチが遅いがマルチコアの恩恵を受けられる
- M:N
- M 個の OS スレッドの上で N 個のユーザー空間スレッドが動く
- コンテキストスイッチが速い上にマルチコアの恩恵も受けられる
- ただしスケジューラの扱いが煩雑
- Go はこれ