插件窝 干货文章 Go并发编程:如何高效并发获取游戏信息并优雅处理超时?

Go并发编程:如何高效并发获取游戏信息并优雅处理超时?

goroutine resultChan context 超时 796    来源:    2025-03-15

在Go语言中,高效并发获取游戏信息并优雅处理超时可以通过使用goroutinechannelcontext来实现。以下是一个示例代码,展示了如何实现这一目标。

1. 使用goroutine并发获取游戏信息

我们可以为每个游戏信息请求启动一个goroutine,这样可以并发地获取多个游戏的信息。

2. 使用channel传递结果

每个goroutine将获取到的游戏信息通过channel传递回主goroutine

3. 使用context处理超时

通过context设置超时时间,确保在指定时间内获取到所有游戏信息,否则取消未完成的请求。

示例代码

package main

import (
    "context"
    "fmt"
    "math/rand"
    "sync"
    "time"
)

// 模拟获取游戏信息的函数
func fetchGameInfo(ctx context.Context, gameID int, resultChan chan<- string, wg *sync.WaitGroup) {
    defer wg.Done()

    // 模拟网络延迟
    delay := time.Duration(rand.Intn(500)) * time.Millisecond
    select {
    case <-time.After(delay):
        resultChan <- fmt.Sprintf("Game %d info fetched", gameID)
    case <-ctx.Done():
        // 如果超时或被取消,返回错误信息
        resultChan <- fmt.Sprintf("Game %d fetch timeout or canceled", gameID)
    }
}

func main() {
    // 创建一个带有超时的context
    ctx, cancel := context.WithTimeout(context.Background(), 300*time.Millisecond)
    defer cancel()

    // 创建一个channel用于接收结果
    resultChan := make(chan string, 10)

    // 使用WaitGroup等待所有goroutine完成
    var wg sync.WaitGroup

    // 模拟并发获取多个游戏信息
    gameIDs := []int{1, 2, 3, 4, 5}
    for _, id := range gameIDs {
        wg.Add(1)
        go fetchGameInfo(ctx, id, resultChan, &wg)
    }

    // 启动一个goroutine等待所有fetchGameInfo完成
    go func() {
        wg.Wait()
        close(resultChan)
    }()

    // 从resultChan中读取结果
    for result := range resultChan {
        fmt.Println(result)
    }
}

代码说明

  1. fetchGameInfo函数:模拟获取游戏信息的操作,通过time.After模拟网络延迟。如果超时或被取消,则返回相应的错误信息。

  2. context.WithTimeout:创建一个带有超时的context,超时时间为300毫秒。如果在超时时间内没有完成所有请求,context会自动取消未完成的请求。

  3. resultChan:用于接收每个goroutine返回的结果。使用buffered channel以避免阻塞。

  4. sync.WaitGroup:用于等待所有goroutine完成。在goroutine完成时调用wg.Done(),主goroutine通过wg.Wait()等待所有goroutine完成。

  5. close(resultChan):在所有goroutine完成后关闭resultChan,以便主goroutine可以退出for range循环。

运行结果

由于fetchGameInfo中模拟了随机延迟,每次运行的结果可能不同。部分结果可能因超时而返回错误信息。

Game 1 info fetched
Game 2 fetch timeout or canceled
Game 3 info fetched
Game 4 fetch timeout or canceled
Game 5 info fetched

总结

通过使用goroutinechannelcontext,我们可以高效地并发获取游戏信息,并优雅地处理超时问题。这种方法适用于需要并发处理多个任务的场景,确保在指定时间内完成任务或及时取消未完成的任务。