go中context的使用场景

使用context在父协程中操作子协程

  • context在go中一般在第一个参数传递
  • context的底层实现是一个树形结构,基于树形结构context有一个比较好的点:关闭父协程时,底层会自动关闭该父协程下的所有子协程,如下示例:基于ctx1继续创建了ctx2,将ctx2传入子协程中, 6s后关闭ctx1, 但ctx1下的ctx2也被关闭了

var wg sync.WaitGroup
func control(ctx context.Context){
	defer wg.Done()
	for {
		select {
		case <-ctx.Done():
			fmt.Println("监控程序退出")
			return
		default:
			fmt.Println("监控信息")
			time.Sleep(time.Second)
			
		}
	}
}
func main() {
	wg.Add(1)
	ctx,cancel1 := context.WithCancel(context.Background())
	ctx2, _ := context.WithCancel(ctx)
	go control(ctx2)
	// 6s 退出
	time.Sleep(time.Second*6)
	cancel1()
	//cancel2()
	wg.Wait()
	fmt.Println("母协程退出")
}

context.WithTimeout 自动退出

var wg sync.WaitGroup
func control(ctx context.Context){
	defer wg.Done()
	for {
		select {
		case <-ctx.Done():
			fmt.Println("监控程序退出")
			return
		default:
			fmt.Println("监控信息")
			time.Sleep(time.Second)
			
		}
	}
}
func main() {
	wg.Add(1)
	// 自动过期
	ctx,_ := context.WithTimeout(context.Background(),time.Second * 6)
	go control(ctx)
	wg.Wait()
	fmt.Println("母协程退出")
}

context 存储数据

  • context 常用来存储一下与业务无关的数据,如 链路ID
  • 原生的context 的数据是存储在树型结构的每个节点,故不适合存储大量数据
var wg sync.WaitGroup
func control(ctx context.Context){
	fmt.Printf("traceid : %v \n",ctx.Value("traceid"))
	defer wg.Done()
	for {
		select {
		case <-ctx.Done():
			fmt.Println("监控程序退出")
			return
		default:
			fmt.Println("监控信息")
			time.Sleep(time.Second)
			
		}
	}
}
func main() {
	wg.Add(1)
	ctx,_ := context.WithTimeout(context.Background(),time.Second * 6)
	ctx = context.WithValue(ctx,"traceid","jjjddddfer")
	go control(ctx)
	wg.Wait()
	fmt.Println("母协程退出")
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值