- Goroutine
Goのランタイムに管理される軽量なスレッドになる。スレッド数やメモリ管理などは、Goがよしなにやってくれるのでそこまで気にしなくても大丈夫(らしい)
go func(x,y)という形で宣言することで、別スレッドで関数を実施できる。mainのGoroutineから外れて、別スレッドに渡される。サンプルは下記の通りになる。
package main
import (
"fmt"
"time"
)
func main() {
go func() { // 別goroutine に渡されて、実行される
fmt.Println("Hello Goroutine")
}()
fmt.Println("Hello Main")
time.Sleep(1 * time.Second)
}
実行結果。別のGorutineで実行されているので、Hello Goroutineが先に帰ってくるかもしれない
% go run main.go
Hello Main
Hello Goroutine
- Channel チャネルオペレータの <- を用いて値の送受信ができる通り道です。この通り道というのはGoroutineとGoroutineを繋ぐという意味での通り道です。下記のように値を送ったり、受信したりすることができる。channelの値格納ポリシーは先入先出であるので、キューとして利用することができる。
ch <- v // channelへvを送信
v := <- ch // channelから受信したものをvという変数にする
channelの定義は下記の通りにできる。2番面の引数は channelをバッファとして利用する際に必要で、格納できる値の個数となる。バッファサイズのデフォルトは0となっており、goroutineでchannelに値を送信後、受信するまでデットロック状態になります。
ch := make(chan int, 100)
channelは開いているか閉じているか、の状態を持っています。これによりfor文などでの対応が可能
v, ok := <- ch
package main
import (
"fmt"
)
func fibonacci(n int, c chan int) {
x, y := 0, 1
for i := 0; i < n; i++ {
c <- x
x, y = y, x+y
}
close(c)
}
func main() {
c := make(chan int, 10)
go fibonacci(cap(c), c) // cap関数でchannelのサイズを取得できる
for i := range c { // channelがクローズになるまで待ち続ける
fmt.Println(i)
}
}
基本的な使い方としてはこれで大丈夫だと思う。適宜mutexを利用した排他制御なども見てください