1

リモート サーバー (ampq チャネル) からの受信メッセージを処理する 2 つの (後で 3 つになります) go ルーチンがあります。しかし、それらは同じデータ/状態で処理しているため、実行中のものを除いて、他のすべての go ルーチンをブロックしたいと考えています。

各 go ルーチンのブロックを使用して解放するソリューションを考え出しましたchan bool。コードは次のようになります。

package main

func a(deliveries <-chan amqp, handleDone chan bool) {
    for d := range deliveries {
        <-handleDone        // Data comes always, wait for other channels
        handleDone <- false // Block other channels

        // Do stuff with data...

        handleDone <- true // I'm done, other channels are free to do anything
    }
}

func b(deliveries <-chan amqp, handleDone chan bool) {
    for d := range deliveries {
        <-handleDone
        handleDone <- false
        // Do stuff with data...
        handleDone <- true
    }
}

func main() {
    handleDone := make(chan bool, 1)
    go a(arg1, handleDone)
    go b(arg2, handleDone)
    // go c(arg3, handleDone) , later

    handleDone <- true // kickstart
}

しかし、初めて各関数が を取得handleDone <- trueし、それが実行されます。後で別の 3 番目の関数を追加すると、事態はさらに複雑になります。実行中以外のすべての go ルーチンをブロックするにはどうすればよいですか? 他のより良い解決策はありますか?

4

3 に答える 3

6

同期パッケージを確認します。

http://golang.org/pkg/sync/

これはミューテックスで行います。

于 2013-03-14T17:27:26.997 に答える
3

メッセージの着信ストリームがあり、そのストリームをリッスンして処理する 3 つのゴルーチンがあり、一度に 1 つのゴルーチンだけが実行されるようにしたい場合、解決策は非常に簡単です。2 つのゴルーチンを強制終了します。

同時実行をスピンアップして複雑さを追加し、それらが同時に実行されないようにしようとしています。最終結果は単一のストリーム リーダーと同じですが、多くのことがうまくいかない可能性があります。

于 2013-03-14T21:36:49.720 に答える
2

なぜこれが必要なのか不思議です。各メッセージをdeliveries個別に処理できないのはなぜですか? そして、これらのメッセージを処理する 2 つの異なる関数があるのはなぜですか? deliveriesそれぞれが特定のタイプのメッセージを担当する場合、タイプに適したロジックにディスパッチする1 つのレシーバーが必要なようです。

trueしかし、あなたの質問に答えるために、各関数が最初から取得されるというのは本当ではないと思いますhandleDone。1つ( だとしましょうa)は、trueから送信されたものを受信して​​いmainます。もう一方 (bその後) はfalse、最初から送信されたものを取得しています。受け取った値を破棄しているため、これはわかりません。そして、両方が実行されており、バッファリングされたチャネルを使用しているため (おそらくmake(chan bool)、代わりにバッファリングされていないチャネルが必要です)、特に 3 番目のゴルーチンを追加するときに混乱が生じます。

実際にはhandleDone <- false何も達成しません。リレーレースでは、任意の値をhandleDoneバトンとして扱います。ゴルーチンがこの値を受け取ると、その目的を果たすことができます。完了したら、次のゴルーチンに渡すためにチャネルに送信する必要があります。

于 2013-03-14T19:37:31.267 に答える