并发编程:context基本方法
注意:context实例是不可变的,每次都是新创建的。
context 包的核心 API 有四个:
context.WithValue:设置键值对,并且返回一个新的 context 实例上下文。
(例如 ThreadLocal 线程本地变量,并发安全的考量,只有我这个线程可访问这个变量,避免并发竞争。)
WithCancel
WithDeadline
WithTimeout:三者都返回一个可取消的 context 实例,和取消函数
控制链路:信号控制、超时控制
type mykey struct {}
// 一般是链路起点,或者调用的起点
ctx := context.Background()
// 在你不确定 context 该用啥的时候,用 TODOC)
ctx := context.TODO()
// Go语言中 空结构类型的变量是不占用任何内存空间的,
// 并且所有该类型的变量都拥有相同的内存地址。
ctx = context.WithValue(ctx,mykey{},"myValue")
// ctx = context.WithValue(ctx,"mykey","myValue")
ctx,cancel := context.WitchCancel(ctx)
// 用完ctx再去带哦用
defer cancel()
go func(){
time.Sleep.(time.Second)
cancel()
}
// 用 ctx
<- ctx.Done()
Log("hello,cancel:",ctx.Err())
// 输出
hello,cancel: context canceled
ctx := context.Backgroud()
ctx,cancel := context.WitchDeadline(ctx,time.Now().Add(time.Second*3))
deadline,_ = := Deadline()
Log("deadline:"deadline)
defer cancel()
<- ctx.Done()
Log("hello,deadline:",ctx.Err())
// 输出
// 取消时间
deadline: 2022-12-24 23:21:17.541241 +0800 CST m=+3.000750528
// 常见提示:context超时
hello, deadline: context deadline exceeded
WitchTimeout内部还是调用WitchDeadline
// WitchDeadline(ctx,time.Now().Add(time.Second*3))
context.WitchTimeout(ctx,time.Second*3)
Context 接口核心 API 有四个:
Deadline:返回过期时间,
如果 ok 为 false,说明没有设置过期时间。略常用
Done:返回一个 channel,一般用于监听 Context 实例的信号,比如说过期,或者正常关闭。常用
一般不单独使用,与select{}一起用。
Err:返回一个错误用于表达Context发生了什么。Canceled => 正常关闭, DeadlineExceeded => 过期超时。比较常用
Value:取值。非常常用
// Value 注意取值用法
val := ctx.Value(mykey{}).(string)
Log (val)
newVal := ctx.Value( key: "不存在的key")
// 如果不取ok,返回不存在key的值为nil,那么转换string时会触发panic
// 所以务必使用ok判断类型转换正确
val, ok := newVal.(string)
if !ok {
t.Log( args...: "类型不对")
return
}
Log(val)
Context是有父子关系的,父代设置了超时时间代表子也设置了超时时间。