GO语言Context介绍

context 包在 Go 语言中用于管理请求范围内的元数据、控制并发操作的生命周期和设置超时等
context 的主要用途包括:

  1. 传递请求范围内的元数据:在处理一个请求的多个函数之间共享信息。
  2. 控制并发操作的生命周期:在多个 Goroutine 之间传递取消信号,控制并发操作的生命周期。
  3. 设置超时和截止时间:防止长期运行的操作,确保系统的响应能力。

Context 接口

Context 接口定义了四个方法:

  1. Deadline() (deadline time.Time, ok bool)

    返回 context 的截止时间。如果未设置截止时间,则 ok 返回 false

  2. Done() <-chan struct{}

    返回一个 channel,当 context 被取消或者超时时,该 channel 会被关闭。通常用于监听取消信号。

  3. Err() error

    返回 context 被取消的原因(取消或超时)。如果 context 未被取消,则返回 nil

  4. Value(key interface{}) interface{}

    返回与 key 相关联的值,通常用于在请求范围内传递请求特定的数据。

常用的 Context 类型和函数

  1. context.Background()

    用作根 context,通常用于 main 函数、初始化和测试中。它是无法取消和无截止时间的基础 context。

  2. context.TODO()

    用作占位符,表示尚未确定使用哪种 context 时的占位符。

  3. context.WithCancel(parent Context) (ctx Context, cancel CancelFunc)

    创建一个可以取消的 context。返回的 cancel 函数用于关闭 context,通知相关 Goroutine 停止工作。

ctx, cancel := context.WithCancel(context.Background())
defer cancel() // 在适当的时机调用取消函数
  1. context.WithTimeout(parent Context, timeout time.Duration) (ctx Context, cancel CancelFunc)

    创建一个带有超时的 context。超过指定时间后,context 会被取消。

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel() // 在超时之前调用取消函数
  1. context.WithDeadline(parent Context, deadline time.Time) (ctx Context, cancel CancelFunc)

    创建一个带有截止时间的 context。到达指定时间后,context 会被取消。

ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(10*time.Minute))
defer cancel() // 在截止时间之前调用取消函数
  1. context.WithValue(parent Context, key, val interface{}) Context

    创建一个带有键值对的 context。用于在请求范围内传递请求特定的数据。

ctx := context.WithValue(context.Background(), "userID", 12345)
value := ctx.Value("userID")

具体使用

1. 取消信号
package main

import (
    "context"
    "fmt"
    "time"
)

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

    go func() {
        select {
            case <-ctx.Done():
            fmt.Println("Goroutine stopped")
        }
    }()

    time.Sleep(1 * time.Second)
    cancel() // 取消操作,通知 Goroutine 停止工作
    time.Sleep(1 * time.Second)
}
2. 超时控制
package main

import (
    "context"
    "fmt"
    "time"
)

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel()

    select {
        case <-time.After(3 * time.Second):
        fmt.Println("operation completed")
        case <-ctx.Done():
        fmt.Println("operation timed out:", ctx.Err())
    }
}
3. 传递请求域数据
package main

import (
    "context"
    "fmt"
)

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

    processRequest(ctx)
}

func processRequest(ctx context.Context) {
    userID := ctx.Value("userID")
    fmt.Println("User ID:", userID)
}

总结

context 包在 Go 中是处理并发操作和请求范围内的数据传递的一个强大工具。通过使用 context 包,我们可以更好地管理 goroutine 的生命周期,确保资源的有效利用和系统的健壮性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值