go をいじって、次のコードをまとめました。
package main
import "fmt"
const N = 10
func main() {
ch := make(chan int, N)
done := make(chan bool)
for i := 0; i < N; i++ {
go (func(n int, ch chan int, done chan bool) {
for i := 0; i < N; i++ {
ch <- n*N + i
}
done <- true
})(i, ch, done)
}
numDone := 0
for numDone < N {
select {
case i := <-ch:
fmt.Println(i)
case <-done:
numDone++
}
}
for {
select {
case i := <-ch:
fmt.Println(i)
default:
return
}
}
}
基本的に、N 個のチャネルで何らかの作業を行い、同じチャネルで報告しています。すべてのチャネルがいつ完了したかを知りたいのです。したがってdone
、各ワーカーゴルーチンがメッセージを送信するこの別のチャネルがあり (メッセージは重要ではありません)、これにより main はそのスレッドを完了としてカウントします。カウントが N になると、実際には完了です。
これは「いい」ですか?これを行うためのより慣用的な方法はありますか?
done
編集:少し明確にするために、チャネルがチャネルの閉鎖が目的と思われる仕事をしているように見えるので、私は疑わしいですが、もちろん、すべてのルーチンが同じチャネルを共有するため、ゴルーチンで実際にチャネルを閉じることはできません. だから私はdone
、ある種の「バッファリングされた閉鎖」を行うチャネルをシミュレートするために使用しています。
edit2: 元のコードは実際には機能していませんでした。done
これは、ルーチンからのシグナルが、ちょうど置かれた int の前に読み取られることがあったためch
です。「クリーンアップ」ループが必要です。