2

したがって、今は、Queueオブジェクトへのポインタを渡し(実装は実際には重要ではありません)queue.add(result)、キューに物事を追加する必要があるゴルーチンの最後で呼び出します。

同じ種類の機能が必要です。もちろん、コンマok構文を使用してループチェックの完了を行うことは、単純なキュー追加関数呼び出しと比較して、パフォーマンスの観点からは受け入れられません。

これをより良くする方法はありますか?

4

1 に答える 1

1

あなたの質問には、実際には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が完了する前に終了します。ゴルーチンを同期することを選択した方法は、クリーンアップが適切に終了することを保証するために、ダミー値を渡すチャネルをさらにいくつか作成することです。これらのチャネルは特にバッファリングされていないため、送信はロックステップで行われます。

于 2010-07-01T06:07:21.963 に答える