什么情況下使用 ErrGroup VS waitGroup?
共 3919字,需瀏覽 8分鐘
·
2024-05-12 21:46
Goroutine 是編寫 Go 語言并發(fā)程序的強大工具。然而管理協(xié)程,特別是在處理協(xié)程的錯誤時,可能會變得繁瑣。這時,x/sync 包中的 errgroup 就派上用場了。它提供了一種簡化的方法來處理并發(fā)任務及其錯誤。
Example for ErrGroup
下面是一個使用 errorGroup 的例子:
package main
import (
"context"
"errors"
"fmt"
"time"
"golang.org/x/sync/errgroup"
)
func task1(ctx context.Context) error {
fmt.Println("Task 1 started successfully")
select {
case <-time.After(1 * time.Second):
fmt.Println("Task 1 completed successfully")
return nil
case <-ctx.Done():
fmt.Println("Task 1 canceled")
return ctx.Err()
}
}
func task2(ctx context.Context) error {
fmt.Println("Task 2 started successfully")
select {
case <-time.After(2 * time.Second):
fmt.Println("Task 2 processed failed")
return errors.New("Task 2 processed failed due to error")
case <-ctx.Done():
fmt.Println("Task 2 canceled")
return ctx.Err()
}
}
func task3(ctx context.Context) error {
fmt.Println("Task 3 started successfully")
select {
case <-time.After(3 * time.Second):
fmt.Println("Task 3 completed successfully")
return nil
case <-ctx.Done():
fmt.Println("Task 3 canceled")
return ctx.Err()
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel() // Ensure cancellation happens when main() exits
g, ctx := errgroup.WithContext(ctx)
g.Go(func() error {
return task1(ctx)
})
g.Go(func() error {
return task2(ctx)
})
g.Go(func() error {
return task3(ctx)
})
if err := g.Wait(); err != nil {
fmt.Println("Encountered error:", err)
cancel()
} else {
fmt.Println("All tasks completed successfully")
}
}
上面程序的輸出是:
Task 1 started successfully
Task 2 started successfully
Task 3 started successfully
Task 1 completed successfully
Task 2 processed failed
Encountered error: Task 2 processed failed due to error
在這個例子中:
-
我們創(chuàng)建了一個帶有可取消上下文的 errgroup。 -
定義了3個任務,task1 和 task3 在一定時間后模擬成功完成,而 task2 在更長的時間后通過返回錯誤來模擬失敗。 -
使用 g.Go 在單獨的 goroutine 中啟動每個任務。 -
調(diào)用 g.Wait 等待所有任務完成。如果任何任務遇到錯誤,g.Wait() 會立即返回該錯誤。在主執(zhí)行之后,task1 成功完成,task2 遇到了處理失敗,而 task3 由于 task2 中的上述失敗而被取消。
ErrGroup vs WaitGroup
ErrGroup:
-
使用 ErrGroup 來管理并發(fā)任務中的錯誤。它聚合了所有協(xié)程中的錯誤,并返回遇到的第一個錯誤。 -
需要管理多個可能產(chǎn)生錯誤的并發(fā)任務。 -
想要利用上下文取消功能來優(yōu)雅地關閉程序。 -
不想手動檢查多個 WaitGroup 調(diào)用的錯誤 -
它與 Go 的上下文包無縫集成。任何來自協(xié)程的錯誤都會取消上下文,自動停止其他正在運行的任務。
WaitGroup
-
使用 WaitGroup 進行基本同步。它簡單地等待指定數(shù)量的 goroutine 完成后再繼續(xù)。 -
]當你只關心任務完成而不預期錯誤時,它是理想的選擇。 -
它不直接處理錯誤。你需要在每個 goroutine 中檢查錯誤并單獨處理它們。
總結
-
使用 WaitGroup 進行簡單的同步 -
使用 ErrGroup 進行錯誤管理,并希望在優(yōu)雅關閉時有上下文感知的取消。 -
也可以同時使用它們,WaitGroup 用于基本同步,ErrGroup 用于一組任務中的詳細錯誤處理。
相關的 issue[1]
x/sync/errgroup: get all errors: https://github.com/golang/go/issues/23595
評論
圖片
表情
