Go のゴルーチン(Goroutine)
ゴルーチン(Goroutine)
ゴルーチンは Go で並行処理を実現する仕組みである。軽量であり、複数の処理を効率よく並行実行できる。
次の例では、メインの処理を実行しながら、go を使って funcA() をゴルーチンとして実行する。
package main
import (
"fmt"
"time"
)
func funcA() {
for i := 0; i < 10; i++ {
fmt.Print("A")
time.Sleep(10 * time.Millisecond)
}
}
func main() {
go funcA()
for i := 0; i < 10; i++ {
fmt.Print("M")
time.Sleep(20 * time.Millisecond)
}
}
実行結果:
MAAMAAAMAAMAAMAMMMMM
次の例では、チャネルを使ってゴルーチンの終了を待つ。chan はチャネル型を宣言し、<- はチャネルを通じてメッセージを送受信する。
package main
import (
"fmt"
"time"
)
func funcA(chA chan<- string) {
time.Sleep(3 * time.Second)
chA <- "Finished" // チャネルへメッセージを送信する
}
func main() {
chA := make(chan string) // チャネルを作成する
defer close(chA) // 使用後に閉じる
go funcA(chA) // ゴルーチンを開始する
msg := <-chA // チャネルからメッセージを受信する
fmt.Println(msg)
}
実行結果:
Finished
次の例では、select を使って funcA() と funcB() の両方を待つ。
package main
import (
"fmt"
"time"
)
func funcA(chA chan<- string) {
time.Sleep(1 * time.Second)
chA <- "funcA Finished"
}
func funcB(chB chan<- string) {
time.Sleep(2 * time.Second)
chB <- "funcB Finished"
}
func main() {
chA := make(chan string)
chB := make(chan string)
defer close(chA)
defer close(chB)
finflagA := false
finflagB := false
go funcA(chA)
go funcB(chB)
for {
select {
case msg := <-chA:
finflagA = true
fmt.Println(msg)
case msg := <-chB:
finflagB = true
fmt.Println(msg)
}
if finflagA && finflagB {
break
}
}
}
実行結果:
funcA Finished
funcB Finished