首頁  >  文章  >  後端開發  >  如何在 Go 中實作 WaitGroup.Wait() 逾時?

如何在 Go 中實作 WaitGroup.Wait() 逾時?

Susan Sarandon
Susan Sarandon原創
2024-11-12 17:17:01877瀏覽

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)以在等待組完成其任務時發出信號等待。
  • 產生一個 goroutine 來呼叫 wg.Wait() 並在完成後關閉通道。
  • select 語句偵聽要關閉的通道或發生逾時。
  • 如果通道關閉,函數傳回 false,表示正常完成。
  • 如果達到逾時,函數會傳回true,表示逾時。

簡化建議的解決方案

為了更簡單的實現,請考慮以下內容:

  • 關閉通道以發出完成信號發送值。
  • 即使函數終止,也可以使用 defer 關閉通道
  • 如果只需要等待一項作業,請刪除等待群組。
  • 直接使用持續時間而不進行轉換(例如,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) 用於在上下文被取消時發出訊號。
  • 產生一個 goroutine 來等待等待群組並向 ctxDone 通道發出訊號。
  • 選擇語句監聽要取消的上下文或等待群組完成。
  • 如果上下文被取消,則函數將根據等待群組是否已完成等待而傳回。

以上是如何在 Go 中實作 WaitGroup.Wait() 逾時?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn