Golang 基础 Part 6: Context 包
文章讨论了 context
包在 Golang 中的基础知识、怎样使用 context
包以及使用 context
包的时候需要注意的地方。
Context 包
context
包主要用于父子任务之间的同步取消信号,本质上是一种协程调度的方式。可以通过简化对于处理单个请求的多个 Goroutine 之间与请求域的数据、超时和退出等操作。来看两个例子:
1package main
2import(
3 "context"
4 "sync"
5 "fmt"
6 "time"
7)
8// 我们定义一个worker function
9func worker(ctx context.Context, wg *sync.WaitGroup) error {
10 defer wg.Done()
11
12 for {
13 select {
14 case <- ctx.Done():
15 return ctx.Err()
16 default:
17 fmt.Println("hello")
18 }
19 }
20}
21
22func main(){
23 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
24
25 var wg sync.WaitGroup
26 for i := 0; i < 10; i++{
27 wg.Add(1)
28 go worker(ctx, &wg)
29 }
30 time.Sleep(time.Second)
31 cancel()
32
33 wg.Wait()
34}
35
当并发体超时或者 main
主动停止 worker
goroutine 时,worker
goroutine 都可以安全退出。
另外在使用 context
时有两点值得注意:上游任务仅仅使用 context
通知下游任务不再需要,但不会直接干涉和中断下游任务的执行,由下游任务自行决定后续的处理操作,也就是说 context
的取消操作是无侵入的;context
是线程安全的,因为 context
本身是不可变的(immutable),因此可以放心地在多个协程中传递使用。