chennel とは
- goroutine 間の
通信を調整するランタイムオブジェクト
- channel はどんな値でも通信できる。
- マップと同じくチャネルは参照型。
- make()を使って作成する。
- channel にはバッファなしとバッファありがある。
バッファなし channel
同期チャネル。
- 送信データは受信側が直接受け取るしかない
- 受信側が他のことをしていて、受信状態になければ、送信側は待たされる
- 受信側が受信状態なら、送信する
- 送信側が送信しているときは、受信者は受信している。=
同期している
バッファあり channel
非同期チャネル。
- バッファを Queue として扱う。
- 受信側は送信されたデータがなければ待つ。
- 送信側はバッファに空きがあれば、値がバッファへコピーされる間だけ待つ。
- バッファに空きがなければ、送信側はバッファに空きができるまで待つ。
channel の操作
channel を作成する
channel は make ステートメントで作成する。
// バッファなし の int を送受信できる channel ch0 := make(chan int) // 10個のバッファを持つ T 型を送受信できる channel ch1 := make(chan T, 10) // バッファなし の int を送信のみできる channel ch2 := make(chan<- int) // バッファなし の int を受信のみできる channel ch3 := make(<-chan int) // nil channel var ch4 chan int
channel にデータを送信する
// ch0 に 10 というデータを送信する ch0 <- 10
channel を閉じる
close(ch0)
closeを呼び出し、事前に送信された値をすべて受信し終えた後で受信操作を行うと、そのチャネル型のゼロ値がブロックされることなしに ゼロ値が返されます。
受信専用の channel を close() するとエラーとなります。
channel からデータを受信する
// ch0 からデータを受信し、変数 x に格納する x := <- ch0// ch0 からデータを受信すると同時に ch0 が close されたか判定する x, ok := <- ch
nil channelからの受信は永久にブロックされます。
select 文で複数の channel からデータを受信する
func server(op binOp, service chan *request, quit chan bool) { for { select { case req := <-service: go run(op, req) // 待たない case <-quit: return } } }
channel をセマフォのように使う
スループットを制限するようなケースで、バッファありチャネルをセマフォのように使うことができます。
var sem = make(chan int, MaxOutstanding) func handle(r *Request) { sem <- 1 // アクティブキューの空き待ち process(r) // 時間のかかる処理 <-sem // 完了。次のリクエストを処理可能にする } func Serve(queue chan *Request) { for { req := <-queue go handle(req) // handleの終了待ちはしない } }
0 件のコメント:
コメントを投稿