Closed17
go言語による並行処理
Rust好きの自分ですら、並行処理関係はGoの方が書きやすい感じ始めている。
ということでGoでも並行処理を勉強する。
並行処理を扱うための道具
多くの言語
OSスレッドとメモリアクセス同期
Go
ゴルーチンとチャネル
ゴルーチンは呼び出し元とメモリ空間を共有する。
WaitGroup
ひとまとまりの並行処理があったときに、その結果を気にしない。もしくは他に結果を取得する手段があるときに使う。どちらにも当てはまない場合はselect
を使う
Cond
なにかが発生するまで待機したいときに使う
チャネル
受信専用
var dataCh := <-chan interface{}
送信専用
var dataCh := chan<- interface{}
goのチャネルはブロックする
rangeキーワード
チャネルを引数にとり、チャネルが閉じた時に自動でループを終了する。
チャネルを正しく使うコツ
チャネルの所有権を割り振る。
所有権とはチャネルを初期化し、書き込み、閉じるゴルーチンと定義
select
select {
case <- ch1:
// なにかする。
case <- ch2:
// なにかする。
case ch3<-struct{}{}:
// なにかする。
}
caseにはチャネルへの読み書きが書かれる。
どれかが用意できたら、その読み書き操作が実行され、対応する文が実行される。
どれも準備できていなかったらブロックされる。
一様乱数で選択される。
default節
Goによる並行処理中級者への道
ゴルーチン、チャネル、select、syncパッケージに入っているものを、スケールしつつ理解しやすい構造に組み合わせていく方法を身につける
for-select
ループ
for {
select {
}
}
利用されるシナリオ
- チャネルから繰り返し変数を相州する。
- 停止シグナルをもつ無限ループ
ゴルーチンリークを避ける
done
チャネルを使う。
orチャネル
doneチャネルを束ねたいときの設計パターン
再帰とゴルーチンを用いる。
エラーハンドリング
ゴルーチンの中で発生したエラーをどう扱うか?
エラーと所望する値をもつResult構造体みたいなものをチャネルに詰める。
パイプライン
ストリーミング処理をチャネルで実現できる。
contextパッケージ
doneチャネルの強化版
Contextはインターフェース
withXXX
でcontextを受け取って、機能を付加したcontextを生成できる。
このスクラップは2022/05/29にクローズされました