context 是go的基础包
context 的使用场景:1. 控制关闭goruntine , 防止溢出 2. 定时完成goruntine 3. 带参数给 goruntine
对应的有以下几种 context :
context.WithCancel context.WithDeadline context.WithTimeout context.WithValue
context.Background() 用来 new 一个新 context context.TODO() 用来 new 一个context 备用
类关系:
源码解析:
查看 go 源码或 看 http://www.codebaoku.com/godeep/goddeep-context-src.html
使用参照:
cancel:
gen := func(ctx context.Context) chan int {
dst := make(chan int)
n := 1
go func() {
fmt.Println("new go ")
for {
select {
case <-ctx.Done():
fmt.Println("goroutine over")
return // return结束该goroutine,防止泄露
case dst <- n:
n++
}
}
}()
return dst
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel() // 当我们取完需要的整数后调用cancel
for n := range gen(ctx) {
fmt.Println(n)
if n == 5 {
break
}
}
deadline / timeout
d := time.Now().Add(50 * time.Millisecond)
ctx, _ := context.WithDeadline(context.Background(), d)
// ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
// 尽管ctx会过期,但在任何情况下调用它的cancel函数都是很好的实践。
// 如果不这样做,可能会使上下文及其父类存活的时间超过必要的时间。
// defer cancel() 如果调用, 是主动停止(canceled) goruntine; 如果不调用 则是超时出 deadline exceeded
go func() {
select {
case <-time.After(1 * time.Second):
fmt.Println("sleep ")
case <-ctx.Done():
fmt.Println(ctx.Err())
fmt.Println("over")
return
}
}()
time.Sleep(time.Second * 5)
contextval
type favContextKey string // 定义一个key类型
// f:一个从上下文中根据key取value的函数
f := func(ctx context.Context, k favContextKey) {
if v := ctx.Value(k); v != nil {
fmt.Println("found value:", v)
return
}
fmt.Println("key not found:", k)
}
k := favContextKey("language")
// 创建一个携带key为k,value为"Go"的上下文
// context.TODO()
ctx := context.WithValue(context.Background(), k, "Go")
f(ctx, k)
f(ctx, favContextKey("color"))
————————————————————————
让科技和智能使人更便捷 --- 从我做起
————————————————————————
浙公网安备 33010602011771号