1. Go语言并发模式深度解析(下)
在上一期我们探讨了Go语言中5种基础并发模式后,今天我将继续分享另外5种高级模式的实际应用。这些模式都经过我在多个线上项目的实战验证,特别是游戏服务器和高并发服务场景中,它们能显著提升程序的健壮性和资源利用率。
1.1 预先占位结果模式(Future/Promise)
这个模式特别适合"先响应后计算"的场景。以麻将游戏为例,当玩家胡牌时,系统需要立即播放音效和动画,而倍数的计算可以稍后进行。
go复制// 结果结构体
type FanResult struct {
TotalScore int // 最终倍数
Details string // 计算明细
Err error // 错误信息
}
// Future本质是一个只读通道
type Future <-chan FanResult
// 异步计算函数返回Future
func CalcFanScore(hand Hand) Future {
ch := make(chan FanResult, 1)
go func() {
defer close(ch)
// 模拟耗时计算
time.Sleep(2 * time.Second)
ch <- FanResult{
TotalScore: 11,
Details: "清一色(6)+七对(5)",
}
}()
return ch
}
实战技巧:
- 使用缓冲通道(容量1)避免goroutine泄漏
- 务必在计算完成后关闭通道
- 错误处理要包含在结果结构中
注意:Future模式会创建额外的goroutine,在超高并发场景要考虑使用worker pool来管理这些任务
1.2 Context可控并发模式
Context是Go并发编程的核心控制机制。我们通过麻将出牌超时案例来看其实际应用:
go复制func waitPlayerAction(ctx context.Context, player string) (string, error) {
select {
case <-time.After(5 * time.Second):
return "", fmt.Errorf("玩家%s超时未出牌", player)
case <-ctx.Done():
return "", ctx.Err() // 上层取消
}
}
// 使用示例
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
action, err := waitPlayerAction(ctx, "张三")
if errors.Is(err, context.DeadlineExceeded) {
fmt.Pri
