美文网首页
Go Context浅析

Go Context浅析

作者: 米兰的小铁匠xxm | 来源:发表于2022-04-17 22:06 被阅读0次

在日常开发中,我们通常会在函数的第一个参数设置为 ctx context.context,这就是golang 的 Context包,目的是用来传递上下文信息。

context都能干啥

说起go大家第一反应会想到协程,协程也具有父子关系,主协程与子协程之间存在控制、协同、取消的需求,如:

  1. 主协程和子协程之间的通信问题,如主协程取消后通知子协程进行取消
  2. 如何对上下文信息进行传递,如请求头里的用户信息,设备信息等
  3. 控制下游rpc接口的超时时间,因为请求基于协程,下游响应慢时,会导致协程数激增,内存上涨,严重可导致服务不可用。

context便是为解决上述问题而生,它可以传递取消信息、超时时间以及携带kv信息等。

如何创建context

  1. context.Background() 和context.TODO() 创建最基本的context
  2. context.WithCancel 传入父context,返回新的context和用于取消该新context的函数
  3. context.WithTimeout和context.WithDeadline,也是传入父context,返回新的context和用于取消该新context的函数,内部会设置定时器,到达时间后自动触发cancelFunc
  4. context.WithValue:传入父context一对kv,返回一个新的Context,新的Context内部会记录这对kv,供以后查询
func main() {
    root := context.Background() //初始化
    ctx1 := context.WithValue(root, "k1", 1111) //携带kv的新context
    ctx2, cancel1 := context.WithCancel(ctx1) //带取消信号的context
    defer cancel1()
    ctx3, cancel2 := context.WithTimeout(ctx2, 2*time.Second) //带超时信号
    defer cancel2()
    ctx4 := context.WithValue(ctx2, "k2", "2222")
    ctx5 := context.WithValue(ctx4, "k3", "3333")
    ctx6 := context.WithValue(ctx3, "k4", "4444")
    ctx7, cancel3 := context.WithDeadline(ctx4, time.Now().Add(4*time.Second))
    defer cancel3()
    ctx8, cancel4 := context.WithCancel(ctx6)
    defer cancel4()

    fmt.Println(ctx7.Value("k1"))
    fmt.Println(ctx6.Value("k4"))
    fmt.Println(ctx5.Value("k2"))

    fmt.Println(ctx7)

    go func() {
        select {
        case <-ctx7.Done():
            fmt.Println("ctx7 canceled")
        }
    }()

    go func() {
        select {
        // ctx8会在7之前cancel,因为ctx3被cancel了
        case <-ctx8.Done():
            fmt.Println("ctx8 canceled")
        }
    }()

    time.Sleep(5 * time.Second)
}
//输出
1111
4444
2222
context.Background.WithValue(type string, val <not Stringer>).WithCancel.WithValue(type string, val 2222).WithDeadline(2022-04-17 21:54:16.807868 +0800 CST m=+4.000185716 [3.999804083s])
ctx8 canceled
ctx7 canceled

context有哪些接口

type Context interface {
        Deadline() (deadline time.Time, ok bool)
        Done() <-chan struct{}
        Err() error
        Value(key interface{}) interface{}
}
  • Deadline:获取是否设置了到期时间以及所设置的截止时间。如果有设置过期时间的话,Context会到那个时间点时自动发起取消Context的操作。
  • Done:返回一个通道,如果通道关闭则代表该Context已经被取消;如果返回的为nil,则代表该Context是一个永远不会被取消的Context。
  • Err:返回该Context被取消的原因,如果只使用Context包的Context类型的话,那么只可能返回Canceled(代表被明确取消)或者DeadlineExceeded(因超时而取消)
  • Value:你可能经常看到代码中使用该函数从ctx中获取一个string key中的值,即一个Context内部是可以携带很多kv的, 关于如何存储,可以想象成一个树中的某个节点,每个节点保存了指向父节点的指针,从当前的节点一层层向根节点寻找

相关文章

  • 浅析 go context

    浅析 go context 用法demo WithCancelfunc WithCancel(parent Con...

  • Go Context浅析

    在日常开发中,我们通常会在函数的第一个参数设置为 ctx context.context,这就是golang 的 ...

  • GO 语言context.Context类型

    context.Context类型 context.Context类型(以下简称Context类型)是在Go 1....

  • 2019-06-23

    go 字符串操作性能 浅析 go 性能分析 性能分析函数

  • Golang Context 详细原理和使用技巧

    Golang Context 详细原理和使用技巧 Context 背景 和 适用场景 Context 的背景 Go...

  • go context

    Req-->a-->c--->b---->return (链式调用) 链式调用和我们普通的函数调用是存在差别的:函...

  • Go context

    goroutine要处理的问题? 数据共享 释放回收 github练习代码 context doc blog...

  • Go context

    Go context 在RPC或者Web服务中,当Server端接受一个request的时候,都会开启一个额外的g...

  • Go context

    控制并发有两种经典的方式:WaitGroup和Context WaitGroup:控制多个Goroutine同时完...

  • go context

    context 很重要,总体作用就是 设置程序执行的 deadline 设置程序的截止日期 status...

网友评论

      本文标题:Go Context浅析

      本文链接:https://www.haomeiwen.com/subject/oqtrertx.html