简介
英文:Package context defines the Context type, which carries deadlines,cancelation signals, and other request-scoped values across API boundaries and between processes.
翻译:包上下文定义了上下文类型,该类型在API边界之间以及进程之间传递截止日期,取消信号和其他请求范围的值。 context信号传递可以理解为如下图的节点树:

func main() {
ctx_a, cancel := context.WithCancel(context.Background())
ctx_b, _ := context.WithCancel(ctx_a)
ctx_c, _ := context.WithCancel(ctx_a)
ctx_e, _ := context.WithCancel(ctx_c)
ctx_f, _ := context.WithCancel(ctx_c)
go run("ctx_b", ctx_b)
go run("ctx_c", ctx_c)
go run("ctx_e", ctx_e)
go run("ctx_f", ctx_f)
cancel()
time.Sleep(time.Second)
}
func run(name string, ctx context.Context) {
select {
case <-ctx.Done():
{
//do somthing
fmt.Println(name, "收到信号")
}
default:
fmt.Println("未收到信号")
}
}
结果:
ctx_c 收到信号
ctx_b 收到信号
ctx_e 收到信号
ctx_f 收到信号
Context 接口
type Context interface {
//返回设置运行的截止日期,如果返回的ok变量等于false,说明这个context没有设置截至日期,ok等于true时说明context设置了截止日期。
// 多次调用也只会返回相同的结果。
Deadline() (deadline time.Time, ok bool)
//返回一个只读的 channel,一般用来接收父context发送的取消信号。
Done() <-chan struct{}
//返回context被取消原因,如果context没有被取消时Err()返回空。
Err() error
//用于存储关联数据,键值对
Value(key interface{}) interface{}
}
Context 继承
func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
func WithValue(parent Context, key, val interface{}) Context
- WithCancel:传递一个父 Context,返回子 Context及取消函数。
func main() {
w := &sync.WaitGroup{}
w.Add(1)
ctx_a, cancel := context.WithCancel(context.Background())
go func() {
select {
case <-ctx_a.Done():
fmt.Println("ctx_a完成了")
w.Done()
default:
fmt.Println("ctx_a没有完成")
}
}()
cancel()
w.Wait()
}
//输出:
//ctx_a完成了
- WithDeadline和WithTimeout:传递一个父 Context和截止时间点(时间间隔),返回子 Context及取消函数。到了时间截止点,自动通知context完成,当然你也可以提前调用cancel去取消context。
func main() {
w := &sync.WaitGroup{}
w.Add(1)
//设置5秒之后截止
ctx_a, _ := context.WithDeadline(context.Background(), time.Now().Add(time.Second*5))
go func() {
i := 0
for {
select {
case <-ctx_a.Done():
fmt.Println("ctx_a完成了")
w.Done()
return
case <-time.After(time.Second):
i++
fmt.Println(i, "秒")
}
}
}()
//提前调用cancel取消
//cancel()
w.Wait()
}
//输出:
//1 秒
//2 秒
//3 秒
//4 秒
//ctx_a完成了
- WithValue:传递一个父 Context和一对键值,返回子 Context。WithValue主要用于context关联一堆键值数据,它没有取消函数功能。一般通过继承父context来实现取消函数。
func main() {
w := &sync.WaitGroup{}
w.Add(1)
//设置5秒之后截止
ctx_a, _ := context.WithDeadline(context.Background(), time.Now().Add(time.Second*5))
ctx_b := context.WithValue(ctx_a, "name", "ctx_b")
go func() {
i := 0
for {
select {
case <-ctx_b.Done():
fmt.Println(ctx_b.Value("name"), "完成了")
w.Done()
return
case <-time.After(time.Second):
i++
fmt.Println(i, "秒")
}
}
}()
//提前调用cancel取消
//cancel()
w.Wait()
}
//输出:
//1 秒
//2 秒
//3 秒
//4 秒
//ctx_b 完成了
emptyCtx
An emptyCtx is never canceled, has no values, and has no deadline.
不能取消,没有存储数据,没有截止日期,说罢了就是一个空的context。
background = new(emptyCtx)
todo = new(emptyCtx)
- context.background: 它通常由主要用于初始化和测试使用,并用作传入的顶级上下文。相当于context节点树的根root。
- context.todo: 当尚不清楚要传递什么context时或者不用的context可以用这个来当中参数
参考:
修改时间:2019/11/18