golang-context使用

本文详细介绍了Golang中Context包的使用方法,包括如何通过context.WithDeadline和context.WithCancel设置超时和取消操作,以及如何在子goroutine中正确响应这些信号。通过具体示例,展示了如何在复杂的goroutine树中保持一致性,实现资源的有效管理和任务的及时终止。

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

context

golang 中的创建一个新的 goroutine , 并不会返回像c语言类似的pid,所有我们不能从外部杀死某个goroutine,所有我就得让它自己结束,之前我们用 channel + select 的方式,来解决这个问题,但是有些场景实现起来比较麻烦,例如由一个请求衍生出的各个 goroutine 之间需要满足一定的约束关系,以实现一些诸如有效期,中止routine树,传递请求全局变量之类的功能。于是google 就为我们提供一个解决方案,开源了 context 包。使用 context 实现上下文功能约定需要在你的方法的传入参数的第一个传入一个 context.Context 类型的变量。

用法

设置结束时间,时间到后,结束parent和child

//如果child的超时时间比parent晚,那么以父类的为准,父类结束,都结束
func TestDeadline(t *testing.T) {
	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second))

	child, _ := context.WithDeadline(ctx, time.Now().Add(10*time.Second))
	go func(ctx context.Context) {
	PROCESS:
		for {
			time.Sleep(2 * time.Second)
			select {
			case <-ctx.Done():
				fmt.Println(ctx.Err())
				break PROCESS
			default:
				fmt.Println("this is from child")
			}
		}
	}(child)

	time.Sleep(20 * time.Second)
	//如果已经超时,这个不起作用
	cancel()
	<-ctx.Done()
	<-child.Done()
	fmt.Println(ctx.Err())
	fmt.Println(child.Err())
}

设置超时时间

//内部调用了DeadLine,和Deadline一样

取消context,父类调用cancle后,子类也会结束

func TestCancelChild(t *testing.T) {
	ctx, cancel := context.WithCancel(context.Background())

	child, _ := context.WithCancel(ctx)
	go func(ctx context.Context) {
		for {
			time.Sleep(2 * time.Second)
			select {
			case <-ctx.Done():
				fmt.Println(ctx.Err())
			default:
				fmt.Println("this is from child")
			}
		}
	}(child)

	time.Sleep(5 * time.Second)
	cancel()
	time.Sleep(5 * time.Second)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值