package main
import (
"fmt"
"sync"
)
// 定义不同类型的结果结构体
type CalculationResult struct {
Value int
}
type StatusInfo struct {
Status string
}
// 定义最终汇总的结果结构体
type AllResults struct {
Calculation CalculationResult
Status StatusInfo
}
func calculationTask() (CalculationResult, error) {
// 模拟计算任务
result := CalculationResult{Value: 42}
return result, nil
}
func statusTask() (StatusInfo, error) {
// 模拟状态任务
status := StatusInfo{Status: "success"}
return status, nil
}
func main() {
var wg sync.WaitGroup
calculationChan := make(chan CalculationResult, 1)
statusChan := make(chan StatusInfo, 1)
errorChan := make(chan error, 2)
// 启动计算任务协程
wg.Add(1)
go func() {
defer wg.Done()
result, err := calculationTask()
if err != nil {
errorChan <- err
} else {
calculationChan <- result
}
}()
// 启动状态任务协程
wg.Add(1)
go func() {
defer wg.Done()
status, err := statusTask()
if err != nil {
errorChan <- err
} else {
statusChan <- status
}
}()
go func() {
wg.Wait()
close(calculationChan)
close(statusChan)
close(errorChan)
}()
var allResults AllResults
var hasError bool
for i := 0; i < 2; i++ {
select {
case result := <-calculationChan:
allResults.Calculation = result
case status := <-statusChan:
allResults.Status = status
case err := <-errorChan:
fmt.Println("Error:", err)
hasError = true
}
}
if!hasError {
fmt.Println("All results:", allResults)
}
}
- 协程间同步:
- 使用
sync.WaitGroup
来等待所有协程完成。在启动每个协程前调用 wg.Add(1)
,在协程结束时调用 wg.Done()
。
- 当所有协程都调用了
wg.Done()
后,通过一个独立的 go
协程关闭相关的通道,这样可以确保在所有协程完成后,通道关闭,不会出现死锁。
- 错误处理:
- 每个任务函数(如
calculationTask
和 statusTask
)返回结果的同时也返回错误。
- 在协程内部,如果任务函数返回错误,将错误发送到
errorChan
通道。在主协程中,通过监听 errorChan
来处理错误。
- 多返回值整合:
- 为不同类型的结果创建不同的通道(如
calculationChan
和 statusChan
)。
- 每个协程将其结果发送到对应的通道。
- 在主协程中,通过
select
语句监听不同的通道,将结果整合到 AllResults
结构体中。