Go select ステートメントの優先順位の回避策
次のシナリオを考えてみましょう。Go ルーチンで 2 つのチャネルを監視し、両方のチャネルがブロックされている場合はブロックされたままにしたいとします。空の。ただし、両方のチャネルにデータが含まれている場合は、一方のチャネルをアドレス指定する前に、もう一方のチャネルを排出することを優先します。
元の問題:
提供されたコード サンプルには、出力チャネルがあります。そして出口チャネル。終了信号を処理する前に、すべての out 値を処理する必要があります。ただし、select ステートメントには優先順位メカニズムが組み込まれていません。
回避策:
Go はこの優先順位付けをネイティブにサポートしているため、回避策は必要ありません。解決策には、プロデューサのみが終了チャネルにアクセスできるようにすることが含まれます。プロデューサーが終了すると、終了チャネルを閉じます。コンシューマは、out チャネルが空になり終了チャネルが閉じるまで、out チャネルからの読み取りを続けます。
変更されたコードは次のようになります。
package main import ( "fmt" "math/rand" "time" ) var ( produced = 0 processed = 0 ) func produceEndlessly(out chan int, quit chan bool) { defer close(out) for { select { case <-quit: fmt.Println("RECV QUIT") return default: out <- rand.Int() time.Sleep(time.Duration(rand.Int63n(5e6))) produced++ } } } func main() { vals, quit := make(chan int, 10), make(chan bool) go produceEndlessly(vals, quit) for x := range vals { fmt.Println(x) processed++ time.Sleep(time.Duration(rand.Int63n(5e8))) } fmt.Println("Produced:", produced) fmt.Println("Processed:", processed) }
説明:
変更されたコードでは、プロデューサーのゴルーチンのみが終了チャネルにアクセスできます。プロデューサーが終了すると、終了チャネルを閉じます。コンシューマのゴルーチンは、out チャネルが空になり、quit チャネルが閉じられるまで、out チャネルからの読み取りを続けます。これにより、コンシューマが終了する前に、すべての out 値が確実に処理されます。
以上がGo の「select」ステートメントでチャネル読み取りに優先順位を付けるにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。