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

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

Patricia Arquette
Patricia Arquetteオリジナル
2024-12-01 09:06:14311ブラウズ

How Can I Prioritize Channels in Go's Select Statement?

Go の Select ステートメントでの優先順位の実装

Go の select ステートメントを使用すると、ゴルーチンを複数のチャネルで多重化し、最初に準備ができたチャネルからのデータを処理できます。 。ただし、チャネルの優先順位付けはネイティブにサポートされていません。この記事では、select ステートメント内で特定のチャネルを他のチャネルよりも優先したいという一般的なプログラミング シナリオについて説明します。

この例では、ゴルーチンは out と exit の 2 つのチャネルにデータを送信します。最初は両方のチャネルが空ですが、その目的は、終了を処理する前にすべての値が処理されるように優先順位を付けることです。質問にあるように、標準の select ステートメントを使用しても、この望ましい動作は実現されません。

この問題に対処するために、Go は洗練されたソリューションを提供します。 select の組み込みの優先順位付けに依存するのではなく、優先順位を付ける必要があるチャネル (この場合は exit) は、送信側のゴルーチンのみがアクセスできるようにする必要があります。送信側のゴルーチンは終了の準備ができると、チャネルを閉じます。レシーバーのゴルーチンは、範囲ベースのループを使用してチャネル (x := range vals の場合) を反復処理し、チャネルが閉じられるまでデータの処理を続けます。

このソリューションを実装すると、次のコードが生成されます。

package main

import (
    "fmt"
    "math/rand"
    "time"
)

var (
    produced  = 0
    processed = 0
)

func produceEndlessly(vals chan int, quit chan bool) {
    defer close(vals)
    for {
        select {
        case vals <- rand.Int():
            produced++
        case <-quit:
            return
        }
    }
}

func quitRandomly(quit chan bool) {
    d := time.Duration(rand.Int63n(5e9))
    fmt.Println("SLEEP", d)
    time.Sleep(d)
    fmt.Println("SEND QUIT")
    quit <- true
}

func main() {
    vals, quit := make(chan int, 10), make(chan bool)
    go produceEndlessly(vals, quit)
    go quitRandomly(quit)
    for x := range vals {
        fmt.Println(x)
        processed++
        time.Sleep(time.Duration(rand.Int63n(5e8)))
    }
    fmt.Println("Produced:", produced)
    fmt.Println("Processed:", processed)
}

この更新されたコードでは、終了チャネルは送信側ゴルーチンからのみ通信されます。これにより、送信者が終了する準備ができるまで終了が選択されなくなります。その結果、受信側の goroutine は、exit を処理する前に vals からのすべてのデータを使い果たします。

以上がGo の select ステートメントでチャネルに優先順位を付けるにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。