ホームページ > バックエンド開発 > Golang > Go でチャネルを使用して Goroutine タイムアウトを確実にオーバーライドするにはどうすればよいですか?

Go でチャネルを使用して Goroutine タイムアウトを確実にオーバーライドするにはどうすればよいですか?

Susan Sarandon
リリース: 2024-12-14 20:56:21
オリジナル
224 人が閲覧しました

How Can I Reliably Override Goroutine Timeouts Using Channels in Go?

チャネルを使用したゴルーチンのタイムアウトのオーバーライド

Golang では、非同期タスクにゴルーチンとチャネルを使用するときに、タイムアウトを指定して次のことを保証できます。操作が無期限にハングすることはありません。ただし、特定のシナリオでは、タイムアウトのケースが期待どおりに実行されない可能性があります。

次のコード スニペットを考えてみましょう:

package main

import (
    "fmt"
    "time"
)

func main() {
    c1 := make(chan int, 1) // Buffered channel with capacity 1

    go func() {
        for {
            time.Sleep(1500 * time.Millisecond) // Sleep for 1.5 seconds
            c1 <- 10 // Send value to channel
        }
    }()

    go func() {
        for {
            select {
            case i := <-c1:
                fmt.Println(i)
            case <-time.After(2000 * time.Millisecond):
                fmt.Println("TIMEOUT") // Not executed
            }
        }
    }()

    fmt.Scanln() // Wait for user input
}
ログイン後にコピー

このコードには、2 つのゴルーチンがあります。1 つは定期的に送信します。 1 つはバッファリングされたチャネル c1 への値で、もう 1 つは 2 秒のタイムアウトで c1 から選択されます。ただし、タイムアウトの場合 (「TIMEOUT」) は出力されません。

この理由は、バッファリングされたチャネルの性質とタイムアウトの処理方法にあります。このシナリオでは、値を c1 に送信するゴルーチンは、1.5 秒ごとにチャネルを継続的に補充します。その結果、2 番目のゴルーチンの select ステートメントは、タイムアウトが期限切れになる前に常に c1 から値を受け取ります。

この問題を修正し、タイムアウト ケースが確実に実行されるようにするには、タイムアウト チャネルを外部に作成する必要があります。選択ループ。これにより、c1:

timeout := time.After(2000 * time.Millisecond) // Create timeout channel only once
for {
    select {
    case i := <-c1:
        fmt.Println(i)
    case <-timeout:
        fmt.Println("TIMEOUT")
    }
}
ログイン後にコピー

から値を受信するたびに破棄されることがなくなります。この変更により、select ステートメントは c1 からの選択を継続しますが、指定されたタイムアウト内に値が受信されなかった場合、 「TIMEOUT」ケースが実行されます。

以上がGo でチャネルを使用して Goroutine タイムアウトを確実にオーバーライドするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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