Golang
中,context
为我们提供了在跨API
边界和进程之间传递请求作用域的deadline
,取消信号,和其他请求响应的值的能力。
context
包定义了Context
类型,它在API
边界和进程之间提供了一种传递传递请求作用域的deadline
,取消信号,和其他请求响应的值的能力。一个Context
的生命周期通常与请求处理的生命周期相同,并且可以包含在多个API
调用和goroutine
之间共享数据和取消信号。
context
的主要方法有:
Deadline
:返回当前Context
合适会被取消。如果Context
不会被取消,则返回ok为false
;Done
:返回一个通道,当Context
被取消或超时的时候,该通道会被关闭。Err
:返回Context
为何被取消。Value
:返回与Context
相关的值,这些值必须是线程安全的。
Go
语言的context
包提供了两个函数用于创建Context
对象:context.Background()
和context.TODO()
,前者通常用在主函数、初始化以及测试代码中,表示一个空的Context
,后者通常用在不确定应该使用什么Context
,或者函数以后会更新以便接受一个Context
参数。
此外,context
包还提供了WithCancel
,WithDeadline
,WithTimeout
和WithValue
函数,从现有的Context
派生出新的Context
。
- context.Background(): 返回一个空的Context,这个Context通常被用在main函数、初始化以及测试时。
- context.TODO(): 当不确定应该使用什么Context,或者还未决定如何传递Context时,可以使用这个。
- context.WithCancel(parent Context) (ctx Context, cancel CancelFunc): 根据已有的Context创建一个新的可取消的Context。
- context.WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc): 根据已有的Context和设置的截止时间创建一个新的Context。
- context.WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc): 基于已有的Context和指定的超时时间创建一个新的Context。
使用场景:
- 超时控制:我们可以通过
context.WithTimeout
创建一个超时的Context
,当超时时间到达,该Context
就会自动取消。比如,在数据库操作或外部服务调用时,可以通过设置超时的context
来防止系统因为某个部分的响应缓慢而整体性能下降。 - 请求传递:在微服务或者并发编程的环境中,我们可以通过
context.WithValue
将请求相关的数据绑定到Context
中,在函数调用链路上下游之间传递。 - 请求取消:我们可以通过
Context.WithCancel
或context.WithTimeout
创建一个可被取消的Context
,并在需要取消的时候调用Context
的cancel
函数。比如在Web服务器中,如果客户端中断了请求,服务器可以通过context
来取消所有相关的goroutine
,从而避免资源浪费。 - 优雅地处理goroutine的生命周期: 通过
context
的Done
通道,可以监听到取消信号,从而在goroutine
中适时地释放资源,停止执行,保证程序的健売性和响应性。
package mainimport ("context""time"
)func calculate(ctx context.Context, ch chan []int) {for {select {case data := <-ch:// 模拟一些处理过程process(data)case <-ctx.Done():// 如果context收到取消信号(超时或显式取消),则停止操作return}}
}func process(data []int) {// 实际处理数据的函数
}func ContextCase() {ctx := context.Background() // 创建一个背景contextctx = context.WithValue(ctx, "desc", "ContextCase") // 向context中添加键值对,这里添加描述信息"ContextCase"// 创建一个带有超时的context,超时时间为2秒ctx, cancel := context.WithTimeout(ctx, time.Second*2)defer cancel() // 确保在函数结束时取消context,以释放相关资源data := [][]int{ // 初始化数据{1, 2},{3, 2},}ch := make(chan []int) // 创建一个传递数据的channelgo calculate(ctx, ch) // 启动一个goroutine来处理从channel接收的数据for i := 0; i < len(data); i++ {ch <- data[i] // 向channel发送数据}time.Sleep(time.Second * 10) // 主goroutine睡眠10秒
}
最后给大家推荐一个LinuxC/C++高级架构系统教程的学习资源与课程,可以帮助你有方向、更细致地学习C/C++后端开发,具体内容请见 https://xxetb.xetslk.com/s/1o04uB