WaitGroup.Wait() のタイムアウト
WaitGroup.Wait() は、すべてのゴルーチンが完了するのを待って無期限にブロックされる可能性があります。これは、実行を無期限にブロックする可能性がある誤ったワーカーからシステムを保護したい場合に問題になる可能性があります。 WaitGroup.Wait() のタイムアウトを設定する慣用的な方法はありませんが、この機能を実現するにはいくつかの方法があります。
一般的な方法の 1 つは、チャネルとゴルーチンの使用です。 goroutine は作業を終了すると、チャネルにシグナルを送信します。メイン プログラムは、チャネルとタイマーを選択して、ゴルーチンがタイムアウトしたかどうかを判断できます。以下に例を示します。
import ( "sync" "time" ) func main() { var wg sync.WaitGroup wg.Add(1) timeout := time.After(5 * time.Second) ch := make(chan struct{}) go func() { defer wg.Done() defer close(ch) // Do some work }() select { case <-ch: // Goroutine finished before timeout wg.Wait() // Wait for all goroutines to finish case <-timeout: // Goroutine timed out wg.Wait() // Block until all goroutines have completed log.Println("Timeout occurred") } }
このソリューションでは、select ステートメントを使用してチャネルまたはタイマーのいずれかを待機し、WaitGroup.Wait() のタイムアウト メカニズムを提供します。その他の推奨される最適化には、defer ステートメントを使用してチャネルを閉じることや、タイムアウト期間に型なし定数を使用することが含まれます。
あるいは、上記の機能をラップするカスタム ヘルパー関数を使用して、コードを簡素化し、再利用しやすくすることもできます。以下に例を示します。
func waitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool { c := make(chan struct{}) defer close(c) go func() { wg.Wait() c <- struct{}{} }() select { case <-c: return false // Completed normally case <-time.After(timeout): return true // Timed out } }
この関数は次のように使用できます。
if waitTimeout(&wg, 5*time.Second) { fmt.Println("Timed out waiting for wait group") } else { fmt.Println("Wait group finished") }
これらのアプローチにより、WaitGroup.Wait() のタイムアウトを設定する方法が提供され、安全性を確保できるようになります。誤ったワーカーがシステムの実行を無期限にブロックすることはありません。
以上がGo で WaitGroup.Wait() のタイムアウトを設定する方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。