Golang-Context扫盲与原理解析

本文详细介绍了Golang中的Context包,包括Context的定义、用途、使用方法及底层实现原理。通过Context,可以控制和管理goroutine,如取消操作、传递共享数据和防止goroutine泄露。文章探讨了Context的四种主要用法,分析了Context接口及其实现,并解释了Context如何实现数据共享和取消机制。最后,总结了Context在并发控制中的重要性和注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Golang-Context扫盲与原理解析

一.什么是Context?

  • context是一个包,是Go1.7引入的标注库,中文译做上下文,准确的说是goroutine的上下文,包含goroutine的运行状态,环境,现场等信息。
  • context主要用于在goroutine之间传递上下文信息,比如取消信号,超时时间,截止时间,kv等。

二.为什么要有Context?

在Go中,控制并发有两种经典的方式,一个是WaitGroup,另外一个就是context

  • WaitGroup:控制多个groutine同时完成,这是等待的方式,等那些必要的goroutine都工作完了我才能工作
  • Context:主动通知某一个groutine结束,这是主动通知的方式,通知某些groutine你不要再工作了

其实主动通知的方式,除了context,还有一种方式也可以实现

  • channle + select
func main() {
	stop := make(chan bool)

	go func() {
		for {
			select {
			case <-stop:
				fmt.Println("监控退出,停止了...")
				return
			default:
				fmt.Println("goroutine监控中...")
				time.Sleep(2 * time.Second)
			}
		}
	}()

	time.Sleep(10 * time.Second)
	fmt.Println("可以了,通知监控停止")
	stop<- true
	//为了检测监控过是否停止,如果没有监控输出,就表示停止了
	time.Sleep(5 * time.Second)
}

采用channle + select 这种方式来实现主动通知,有两个致命的缺点:

  • 只能通知一个groutine结束,无法应对很多goroutine都需要结束的情况
  • 无法应对goroutine又衍生出其他更多的goroutine的情况

上述这两种场景其实在业务中非常的常见

  • 场景1:比如一个网络请求Request,每个Request都需要开启一个goroutine做一些事情,这些goroutine又可能会开启其他的goroutine,具体表现在Go的Server中,通常每一个请求都会启动若干个goroutine同时工作,有些去数据库拿数据,有些调用下游接口获取相关数据,这些goroutine需要共享这个请求的基本数据,例如登录token,处理请求的最大超时时间等等,当请求被取消或是处理时间太长,这时,所有正在为这个请求工作的goroutine都需要快速退出,因为他们的工作成果不再被需要了

为应对上述场景,并且使得goroutine是可追踪的,context应运而生

三.Context 如何使用?

1.context控制多个goroutine

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	go watch(ctx,"【监控1】")
	go watch(ctx,"【监控2】")
	go watch(ctx,"【监控3】")

	time.Sleep(10 * time.Second)
	fmt.Println("可以了,通知监控停止")
	cancel()
	//为了检测监控过是否停止,如果没有监控输出,就表示停止了
	time.Sleep(5 * time.Second)
}

func watch(ctx context.Context, name string) {
	for {
		select {
		case <-ctx.Done():
			fmt.Println(name,"监控退出,停止了...")
			return
		default:
			fmt.Println(name,"goroutine监控中...")
			time.Sleep(2 * time.Second)
		}
	}
}

上述样例,context控制了三个goroutine,当context cancle之后,这三个goroutine便都退出了

2.传递共享数据

packag
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值