したがって、今は、Queueオブジェクトへのポインタを渡し(実装は実際には重要ではありません)queue.add(result)、キューに物事を追加する必要があるゴルーチンの最後で呼び出します。
同じ種類の機能が必要です。もちろん、コンマok構文を使用してループチェックの完了を行うことは、単純なキュー追加関数呼び出しと比較して、パフォーマンスの観点からは受け入れられません。
これをより良くする方法はありますか?
あなたの質問には、実際には2つの部分があります。Goでデータをキューに入れる方法と、ブロックせずにチャネルを使用する方法です。
最初の部分では、チャネルを使用してキューに追加するのではなく、チャネルをキューとして使用する必要があるようです。例えば:
var (
ch = make(chan int) // You can add an int parameter to this make call to create a buffered channel
// Do not buffer these channels!
gFinished = make(chan bool)
processFinished = make(chan bool)
)
func f() {
go g()
for {
// send values over ch here...
}
<-gFinished
close(ch)
}
func g() {
// create more expensive objects...
gFinished <- true
}
func processObjects() {
for val := range ch {
// Process each val here
}
processFinished <- true
}
func main() {
go processObjects()
f()
<-processFinished
}
これをより非同期にする方法については、(cthom06が指摘したように)make2行目の呼び出しに2番目の整数を渡すことができます。これにより、チャネルのバッファーがいっぱいになるまで送信操作が非同期になります。
編集:ただし(cthom06も指摘しているように)、チャネルに書き込みを行う2つのゴルーチンがあるため、そのうちの1つがチャネルを閉じる責任を負う必要があります。また、以前のリビジョンは、processObjectsが完了する前に終了します。ゴルーチンを同期することを選択した方法は、クリーンアップが適切に終了することを保証するために、ダミー値を渡すチャネルをさらにいくつか作成することです。これらのチャネルは特にバッファリングされていないため、送信はロックステップで行われます。