Go Context 使用和代码分析上下文(好理解)
Go语言中的go-routine是go语言中的最重要的一部分,是一个用户级的线程是Go语言实现高并发高性能的重要原因.但是如何停止一个已经开启的go-routine呢?一般有几种方法:
- 使用共享内存来停止go-routine,比如通过判断一个全局变量来判断是否要停止go-routine
- 使用文件系统来停止go-routine,跟使用内存相同用文件来判断
- 使用context上下文,context也是大家最推荐的一种方式.并且可以结束嵌套的go-routine.
简单使用
context库中,有4个关键方法:
WithCancel
返回一个cancel函数,调用这个函数则可以主动停止go-routine.WithValue
WithValue可以设置一个key/value的键值对,可以在下游任何一个嵌套的context中通过key获取value.但是不建议使用这种来做go-routine之间的通信.WithTimeout
函数可以设置一个time.Duration,到了这个时间则会cancel这个context.WithDeadline
WithDeadline函数跟WithTimeout很相近,只是WithDeadline设置的是一个时间点.
package main
import (
"context"
"fmt"
"time"
)
func main() {
//cancel
ctx, cancel := context.WithCancel(context.Background())
go work(ctx, "work1")
time.Sleep(time.Second * 3)
cancel()
time.Sleep(time.Second * 1)
// with value
ctx1, valueCancel := context.WithCancel(context.Background())
valueCtx := context.WithValue(ctx1, "key", "test value context")
go workWithValue(valueCtx, "value work", "key")
time.Sleep(time.Second * 3)
valueCancel()
// timeout
ctx2, timeCancel := context.WithTimeout(context.Background(), time.Second*3)
go work(ctx2, "time cancel")
time.Sleep(time.Second * 5)
timeCancel()
// deadline
ctx3, deadlineCancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second*3))
go work(ctx3, "deadline cancel")
time.Sleep(time.Second * 5)
deadlineCancel()
time.Sleep(time.Second * 3)
}
func workWithValue(ctx context.Context, name string, key string) {
for {
select {
case <-ctx.Done():
fmt.Println(ctx.Value(key))
println(name, " get message to quit")
return
default:
println(