2013年11月11日月曜日

Golang Cafe #3 を開催しました。

Golang Cafe #3を開催しました。

今日のお題はGoroutinesとchannelを使った並列プログラミング(初級)という感じです。githubにコードを置いてあります。

ワーカースレッド(goroutine)を起動するには、呼び出し時にgoを記述する。

Channelを使って、簡単な排他制御ができる。
ch := make(chan int)でChannelを作る。
ch<-1だと、Channelに1を送る。<-chだと、Channelから値を受け取る。

ちょっと、サンプルコードのミスで、よくわからないコードができてしまったが、コンパイルエラーにならないのが不思議だった。該当のソースコードはこちら

break、continueの使い方
言語仕様を参照。基本的にラベルの次のfor、switch、selectを抜ける。
continueはラベルの次のforをもう一度実行。

selectについて。言語仕様を確認した感じ。
select文にdefaultを入れると、defaultを呼び出して抜けてしまう。ただし、defaultがなければ、caseのどれかが呼ばれるまで処理をブロックする。

select{}にすると、無限に待ち続ける。

time.Tick()とtime.After()を同時に呼び出して、selectで同時に待ち受けるとtime.After()が永久に戻ってこない?(ただし、time.TickでのChannelの応答の前に、time.After()のタイミングがあると、呼び出される)
バグ…?
と思っていたら、+Fumitoshi Ukaiさんから、正しい書き方を教えていただきました!ありがとうございました。

runtime.GOMAXPROCS(n)を呼び出すと、CPUの利用数が設定できる。(戻り値は前の設定なので注意!)これを呼び出すと、goroutinesが並列に処理されるようになる。
が、アクティビティモニタで確認したら、スレッド数は6だった。(2を期待したけど、Go言語ランタイム(?)の方のスレッドがいるんだろうか。)

関数の引数で、channelが「送信専用」か「受信専用」かを明示することができる。
送信専用=ch chan<- int
受信専用=ch <-chan int
間違いがあると、コンパイル時にエラーになる。

次回は、database/sqlパッケージを使って、DBにアクセスする回になりそうです。