Context是由Golang官方开发的并发控制包,一方面可以用于当请求超时或者取消时候,相关的goroutine马上退出释放资源,
另一方面Context本身含义就是上下文,其可以在多个goroutine或者多个处理函数之间传递共享的信息。
创建一个新的context,必须基于一个父context,新的context又可以作为其他context的父context。
所有context在一起构造成一个context树。
package main
import (
"context"
"fmt"
"math/rand"
"runtime"
"time"
)
func main(){
//ctx 超时控制
ctx,cancel:=context.WithTimeout(context.Background(),3*time.Second)
defer cancel()
go SlowOperation(ctx)
go func() {
for {
time.Sleep(300*time.Microsecond)
fmt.Println("goroutine:",runtime.NumGoroutine())
}
}()
time.Sleep(4*time.Second)
}
func SlowOperation(ctx context.Context){
done:=make(chan int,1)
go func() {
dur:=time.Duration(rand.Intn(5)+1)*time.Second
time.Sleep(dur)
done
}()
select {
case
fmt.Println("slowOperation timeout:",ctx.Err())
case
fmt.Println("complete work")
}
}
上面代码会不停打印当前groutine数量,可以观察到SlowOperation函数执行超时之后,goroutine数量由4个变成2个,相关goroutetine退出了
type Context interface {
Deadline() (deadline time.Time, ok bool)
Done()
Err() error
Value(key interface{}) interface{}
}
Context接口一共包含四个方法:
Deadline:返回绑定该context任务的执行超时时间,若未设置,则ok等于false
Done:返回一个只读通道,当绑定该context的任务执行完成并调用cancel方法或者任务执行超时时候,该通道会被关闭
Err:返回一个错误,如果Done返回的通道未关闭则返回nil,如果context如果被取消,返回Canceled错误,如果超时则会返回DeadlineExceeded错误
Value:根据key返回,存储在context中k-v数据