Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > golang Context使用

golang中Context的使用场景

作者:Senkorl

context包提供了一种在goroutine之间传递信号的方法,用于管理请求的生命周期和控制并发操作,本文主要介绍了golang中Context的使用场景,下面就来介绍一下,感兴趣的可以了解一下

在 Go 语言中,context 包提供了一种在 goroutine 之间传递信号的方法,用于管理请求的生命周期和控制并发操作。context 主要用于以下几个场景:

1. 控制请求的生命周期

场景描述

使用示例

func handler(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()
    resultChan := make(chan string)

    go func() {
        // 模拟耗时操作
        time.Sleep(2 * time.Second)
        resultChan <- "result"
    }()

    select {
    case <-ctx.Done():
        // 请求取消或超时
        http.Error(w, "request canceled", http.StatusRequestTimeout)
    case result := <-resultChan:
        // 正常返回结果
        fmt.Fprintln(w, result)
    }
}

2. 处理超时和截止日期

场景描述

使用示例

func fetchData(ctx context.Context) (string, error) {
    ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
    defer cancel()

    ch := make(chan string, 1)
    go func() {
        // 模拟耗时操作
        time.Sleep(3 * time.Second)
        ch <- "data"
    }()

    select {
    case <-ctx.Done():
        return "", ctx.Err() // 返回超时或取消错误
    case result := <-ch:
        return result, nil
    }
}

3. 传递元数据

场景描述

使用示例

func main() {
    ctx := context.Background()
    ctx = context.WithValue(ctx, "requestID", "12345")

    processRequest(ctx)
}

func processRequest(ctx context.Context) {
    reqID := ctx.Value("requestID")
    fmt.Println("Request ID:", reqID)
}

4. 协同工作

场景描述

使用示例

func main() {
    ctx, cancel := context.WithCancel(context.Background())

    go worker(ctx, "worker1")
    go worker(ctx, "worker2")

    time.Sleep(1 * time.Second)
    cancel() // 取消所有工作

    time.Sleep(1 * time.Second)
}

func worker(ctx context.Context, name string) {
    for {
        select {
        case <-ctx.Done():
            fmt.Println(name, "stopped")
            return
        default:
            fmt.Println(name, "working")
            time.Sleep(500 * time.Millisecond)
        }
    }
}

5. 限制并发数量

场景描述

使用示例

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    sem := make(chan struct{}, 3) // 限制并发数为3
    var wg sync.WaitGroup

    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func(i int) {
            defer wg.Done()
            sem <- struct{}{} // 获取信号
            defer func() { <-sem }() // 释放信号

            worker(ctx, i)
        }(i)
    }

    wg.Wait()
}

func worker(ctx context.Context, id int) {
    select {
    case <-ctx.Done():
        fmt.Printf("worker %d canceled\n", id)
        return
    default:
        fmt.Printf("worker %d working\n", id)
        time.Sleep(1 * time.Second)
    }
}

6. 总结

context 在 Go 语言中主要用于管理请求的生命周期、处理超时、传递元数据、协同工作和限制并发。它提供了一种简洁且强大的方式来管理复杂的并发操作,特别是在涉及多个 goroutine 时。通过合理使用 context,可以编写更健壮、更可控的并发程序。

到此这篇关于golang中Context的使用场景的文章就介绍到这了,更多相关golang Context使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文