type
status
date
slug
summary
tags
category
icon
password
Sub-item
Last edited time
Oct 29, 2023 08:23 AM
Parent item
领域
【场景需求】
控制多个子任务(协程)的运行状态:取消运行或超时退出。
需要一种优雅的方案来实现这样一种机制:
- 上层任务取消后,所有的下层任务都会被取消;
- 中间某一层的任务取消后,只会将当前任务的下层任务取消,而不会影响上层的任务以及同级任务。
【概述】
Context是一个接口,包含以下的方法:
可以实现如下的功能:
- 手动、定时、超时发出取消信号,退出运行任务的协程
- 传值(类似全局变量的作用)
【Context树】
Go 语言提供了函数实现了 Context 接口,可以帮助我们生成不同的 Context,通过这些函数可以生成一颗 Context 树。
- 生成一个根节点 Context :
context.Background()
- 使用 Go 语言提供的四个函数生成不同功能的Context。
WithCancel(parent Context)
:生成一个可取消的 Context。WithDeadline(parent Context, d time.Time)
:生成一个可定时取消的 Context,参数 d 为定时取消的具体时间。WithTimeout(parent Context, timeout time.Duration)
:生成一个可超时取消的 Context,参数 timeout 用于设置多久后取消WithValue(parent Context, key, val interface{})
:生成一个可携带 key-value 键值对的 Context。
【例子】主动通知同时取消多个协程任务
【例子】传递值
典型应用是在Context中保存
traceID
,实现链路跟踪。Context 使用原则
要更好地使用 Context,有一些使用原则需要尽可能地遵守。
- Context 不要放在结构体中,要以参数的方式传递。
- Context 作为函数的参数时,要放在第一位,也就是第一个参数。
- 要使用 context.Background 函数生成根节点的 Context,也就是最顶层的 Context。
- Context 传值要传递必须的值,而且要尽可能地少,不要什么都传。
- Context 多协程安全,可以在多个协程中放心使用。