ホームページ > バックエンド開発 > Golang > Go の「select」ステートメントでチャネル読み取りに優先順位を付けるにはどうすればよいですか?

Go の「select」ステートメントでチャネル読み取りに優先順位を付けるにはどうすればよいですか?

Mary-Kate Olsen
リリース: 2024-12-09 10:21:06
オリジナル
802 人が閲覧しました

How Can I Prioritize Channel Reads in Go's `select` Statement?

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 サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート