Context
介绍
type Context interface {
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{}
Err() error
Value(key any) any
}
使用 WithValue() 传递数据
func A(ctx context.Context) context.Context {
time.Sleep(1 * time.Second)
fmt.Println("A: ", ctx.Value("main"))
ctx = context.WithValue(ctx, "A", "A-1")
go B(ctx)
return ctx
}
func B(ctx context.Context) context.Context {
time.Sleep(1 * time.Second)
fmt.Println("B: ", ctx.Value("main"))
fmt.Println("B: ", ctx.Value("A"))
return ctx
}
func main() {
ctx := context.WithValue(context.Background(), "main", "main-1")
go A(ctx)
time.Sleep(3 * time.Second)
}
使用 WithCancel() 取消操作
func main() {
ctx, cancel := context.WithCancel(context.Background())
go Speak(ctx)
time.Sleep(3 * time.Second)
cancel()
time.Sleep(1 * time.Second)
}
func Speak(ctx context.Context) {
for range time.Tick(time.Second) {
select {
case <-ctx.Done():
fmt.Println("我要闭嘴了")
return
default:
fmt.Println("balabalabalabala")
}
}
}
使用 WithDeadline() 设置截止时间
使用 WithTimeout() 设置超时时间
withTimeout和withDeadline作用是一样的,就是传递的时间参数不同,会通过传入的时间来自动取消Context,都会返回一个cancelFunc方法,通过调用这个方法可以达到提前进行取消
使用的过程还是建议在自动取消后也调用cancelFunc去停止定时减少不必要的资源浪费
func A(in chan struct{}) {
time.Sleep(1 * time.Second)
in <- struct{}{}
}
func B(in chan struct{}) {
time.Sleep(3 * time.Second)
in <- struct{}{}
}
func main() {
var ch1 = make(chan struct{})
var ch2 = make(chan struct{})
var ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second)
go func() {
go A(ch1)
select {
case <-ctx.Done():
fmt.Println("ctx timeout")
break
case <-ch1:
fmt.Println("A Done")
}
}()
go func() {
go B(ch2)
select {
case <-ctx.Done():
fmt.Println("ctx timeout")
break
case <-ch2:
fmt.Println("B Done")
}
}()
defer cancel()
time.Sleep(5 * time.Second)
}