Go语言中context原理及使用

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包还提供了WithCancelWithDeadlineWithTimeoutWithValue函数,从现有的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。
使用场景:
  1. 超时控制:我们可以通过context.WithTimeout创建一个超时的Context,当超时时间到达,该Context就会自动取消。比如,在数据库操作或外部服务调用时,可以通过设置超时的context来防止系统因为某个部分的响应缓慢而整体性能下降。
  2. 请求传递:在微服务或者并发编程的环境中,我们可以通过context.WithValue将请求相关的数据绑定到Context中,在函数调用链路上下游之间传递。
  3. 请求取消:我们可以通过Context.WithCancelcontext.WithTimeout创建一个可被取消的Context,并在需要取消的时候调用Contextcancel函数。比如在Web服务器中,如果客户端中断了请求,服务器可以通过context来取消所有相关的goroutine,从而避免资源浪费。
  4. 优雅地处理goroutine的生命周期: 通过contextDone通道,可以监听到取消信号,从而在goroutine中适时地释放资源,停止执行,保证程序的健売性和响应性。
package main

import (
	"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() // 创建一个背景context
	ctx = 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) // 创建一个传递数据的channel
	go 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

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值