この記事について
Go の goroutine について理解したことをまとめます。
Concurrency (並行性)
goroutine は、Go において concurrency を実現するための技術です。
concurrencry とは、ある期間において複数の処理を行うことです。
Concurrency (並行性) と Parallelism (並列性) は異なる
concurrency と同時によく語られる概念に parallelism があります。
しかし、この2つの概念はそれぞれ別の概念です。
parallelism は、同時に複数の処理を行うことです。
goroutine (ゴルーチン)
A Tour of Go によると
goroutine (ゴルーチン)は、Goのランタイムに管理される軽量なスレッドです。
と説明されています。
由来
Effective Go によると、以下のように説明されています。
They're called goroutines because the existing terms—threads, coroutines, processes, and so on—convey inaccurate connotations.
goroutine の Pros/Cons
goroutine を使用する場合の Pros/Cons について整理します。
Pros
並列実行により、処理を早くする行うことができる可能性がある。
並行性と並列性は異なると説明しましたが、goroutine で書かれたプログラムは並列に実行される可能性があります。
Cons
プログラムの可動性が低下する。
シーケンシャルな処理と異なり、goroutine を使用したプログラムは読みづらくなる可能性があります。
goroutine の使いどころ
goroutine を使用した方が処理が早くなるケース
同時実行可能な複数の処理において、1つの処理が重い場合などに有効です。
goroutine の実装
実装における goroutine の扱い方について説明します。
goroutine の起動
goroutine の起動方法について説明します。
関数やメソッドを呼び出す際に、呼び出す関数の前に go
を付与します。
付与された関数やメソッドは呼び出された際に goroutine として起動します。
関数を goroutine として起動する例
次のコードは、isOver100
関数を goroutine として起動します。
package main
func main() {
println("Started main function")
go isOver100(101)
}
func isOver100(value int) {
var result bool
if value > 100 {
result = true
} else {
result = false
}
println(result)
}
実行結果
Started main function
Process finished with the exit code 0
実行すると、Started main function
とだけ出力されて処理が終了します。
これは、goroutine として起動した関数の処理を待たずに main
関数の処理が終了するためです。
goroutine として起動した関数の処理を待つためには、後述の channel
を使用する必要があります。
channel (チャネル) 型
goroutine 間で情報をやり取りする際に使用します。
例えば、goroutine A と goroutine B が存在していたとして、goroutine A から goroutine B にデータを渡したいときに channel を使用します。
channel の生成
string
型データを送受信するための channel を生成する例
sampleCh := make(chan string)
channel に値を書き込む
channel に値を書き込むには channel operator である <-
を使用します。
文字列 value
を sampleCh
channel に書き込む例
sampleCh <- "value"
channel から値を読み込む
sampleCh
channel から値を読み込む例
val := <-sampleCh
channel を使用して情報をやり取りする例
package main
func main() {
println("Started main function")
sampleCh := make(chan bool)
go isOver100(101, sampleCh)
result := <-sampleCh
println(result)
}
func isOver100(value int, ch chan bool) {
var result bool
if value > 100 {
result = true
} else {
result = false
}
ch <- result
}
実行結果
Started main function
true
Process finished with the exit code 0
channel を使用したことにより、isOver100
関数の処理を待って main
関数の処理が終了しました。