go context
context包是官方定义的一个上下文包,用于在goroutine之间传递上下文用,其采用树状结构,根节点退出后子goroutine也会跟着退出
type Context interface {
// 当 context 被取消或者到了 deadline,返回一个被关闭的 channel
Done() <-chan struct{}
// 在 channel Done 关闭后,返回 context 取消原因
Err() error
// 返回 context 是否会被取消以及自动取消时间(即 deadline)
Deadline() (deadline time.Time, ok bool)
// 获取 key 对应的 value
Value(key interface{}) interface{}
}
创建
context.Background 是上下文的默认值,一般作为根节点在main中使用
context.TODO 应该只在不确定应该使用哪种上下文时使用
以上两种类型想要发挥作用还得搭配各种with方法来说使用
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和cancelfunc
func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
package main
import (
"context"
"fmt"
"sync"
"time"
)
func main() {
ctx, cancel := context.WithCancel(context.Background()) //根
son_ctx, _ := context.WithCancel(ctx) //子
var wg sync.WaitGroup
wg.Add(2)
go func() {
for {
select {
case <-ctx.Done():
fmt.Println("ALL DONE")
fmt.Println(ctx.Err())
wg.Done()
return
default:
fmt.Println("continue")
}
}
}()
go func() {
for {
select {
case <-son_ctx.Done(): //父收到退出信号,子也会跟着退出
fmt.Println("son die too")
wg.Done()
return
}
}
}()
time.Sleep(time.Duration(2) * time.Second)
cancel()
wg.Wait()
}
//continue
//son die too
//ALL DONE
//context canceled
withTimeout/withDeadline
传入一个父context和超时时间
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
func WithDeadline(parent Context, d time.Time) (Context, CancelFunc)
withValue
func WithValue(parent Context, key, val any) Context
传入的键必须是可比较类型,且不能是string等内置类型
package main
import (
"context"
"fmt"
)
func main() {
type favContextKey string
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")
ctx := context.WithValue(context.Background(), k, "Go")
f(ctx, k)
f(ctx, favContextKey("color"))
}
//Output:
//found value: Go
//key not found: color
评论已关闭