ホームページ  >  記事  >  バックエンド開発  >  Go で WaitGroup.Wait() のタイムアウトを実装する方法は?

Go で WaitGroup.Wait() のタイムアウトを実装する方法は?

Susan Sarandon
Susan Sarandonオリジナル
2024-11-12 17:17:01940ブラウズ

How to Implement a Timeout for WaitGroup.Wait() in Go?

WaitGroup.Wait() のタイムアウト: 慣用的なアプローチ

Go では、誤ったワーカーが無限に待機することを防ぐために、WaitGroup.Wait() に時間制限を設定できます。 。ここでは、慣用的な実装方法と代替アプローチを詳しく説明します。

推奨される解決策: タイマーとチャネルの使用

次のアプローチは、最も慣用的な解決策であると広く考えられています。

import (
    "sync"
    "time"
)

func waitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool {
    c := make(chan struct{})
    go func() {
        wg.Wait()
        close(c)
    }()
    select {
    case <-c:
        return false // completed normally
    case <-time.After(timeout):
        return true // timed out
    }
}
  • 待機グループが待機を完了したときに通知するチャネル (c) が作成されます。
  • wg.Wait() を呼び出し、終了時にチャネルを閉じるゴルーチンが生成されます。
  • select ステートメントは、チャネルが閉じられるかタイムアウトが発生するかをリッスンします。
  • チャネルが閉じられると、関数は false を返し、正常に完了したことを示します。
  • タイムアウトに達すると、関数はタイムアウトを示す true を返します。

推奨ソリューションの簡略化

より単純な実装については、次の点を考慮してください。

  • 値を送信する代わりにチャネルを閉じて、完了を通知します。
  • 関数が途中で終了する場合でも、defer を使用してチャネルを閉じます。
  • 1 つのジョブだけを待機する必要がある場合は、待機グループを削除します。 .
  • 変換せずに継続時間を直接使用します (例: time.Second)。

代替アプローチ: キャンセル可能なコンテキストを使用する

代替アプローチには、キャンセル可能なコンテキストを使用することが含まれます。 context:

import (
    "context"
    "sync/atomic"
    "sync"
)

func waitWithCancel(ctx context.Context, wg *sync.WaitGroup) bool {
    ctxDone := make(chan struct{})
    var exited int32
    go func() {
        defer close(ctxDone)
        wg.Wait()
        atomic.StoreInt32(&exited, 1)
    }()

    select {
    case <-ctx.Done():
        return atomic.LoadInt32(&exited) == 0
    case <-ctxDone:
        return true
    }
}
  • キャンセル可能なコンテキスト (ctx) が作成されます。
  • コンテキストがキャンセルされたときに通知するためにチャネル (ctxDone) が使用されます。
  • 待機グループを待機し、ctxDone チャネルに信号を送るゴルーチンが生成されます。
  • select ステートメントは、キャンセルされるコンテキストまたは完了する待機グループのいずれかをリッスンします。
  • コンテキストがキャンセルされた場合、関数は待機グループがすでに待機を終了したかどうかに基づいて戻ります。

以上がGo で WaitGroup.Wait() のタイムアウトを実装する方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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