golang context(SDK1.7 新增部分)

来源:互联网 发布:美工学徒招聘 编辑:程序博客网 时间:2024/06/05 23:57

golang 1.7之后引入了context.

首先看看context,下边是golang sdk源代码中context内容,可以发现他是一个接口,通过定义一种规范,来规定context操作方法.

// 上下文是一个接口.// 这个接口中声明了4个方法.type Context interface {    // Deadline returns the time when work done on behalf of this context    // should be canceled. Deadline returns ok==false when no deadline is    // set. Successive calls to Deadline return the same results.    // 这个方法在timerCtx类中实现.    // 主要服务于定时类型的context服务.    // 通过设置截止时间戳,来规定context的有效期间.    // 只有通过WithDeadline或者WithTimeout才能操作Deadline.    Deadline() (deadline time.Time, ok bool)    // 判断context是否被关闭    // 如果context被取消,则Done返回nil,反之,返回一个有效的地址.    Done() <-chan struct{}    // 当context被取消时,返回一个非nil的值.    // 如果context没有取消,返回nil    Err() error    // 主要用户valueCtx    // 用来存储context中的值.    // 只有通过WithValue得到的context,才能操作Value    // 通过WithValue创建出来的context,只能通过父级context才能使用上边的3个方法.    Value(key interface{}) interface{}}

源代码中实现有两种类,第一种是实现了Context接口,第二种是组合了Context接口.对于这两种方式,是有区别的:
1. 实现了Context接口的类,可以访问Context所有方法
2. 组合了Context接口的类,不一定Context所有方法都可以正常使用.

实现了Context接口的类

emptyCtx实现了context接口.

// An emptyCtx is never canceled, has no values, and has no deadline. It is not// struct{}, since vars of this type must have distinct addresses.type emptyCtx int

下边定义了两个空值context

var (    background = new(emptyCtx)    todo       = new(emptyCtx))

默认情况下,已经存在了上边两个空的context.在后边的应用中,可以将空的context设置为parent context来使用.


组合了Context接口的类

  1. cancelCtx
  2. timerCtx
  3. valueCtx

下边来具体介绍下上述3个组合了Context的类.

cancelCtx类

type cancelCtx struct {    Context    done chan struct{} // closed by the first cancel call.    mu       sync.Mutex    children map[canceler]bool // set to nil by the first cancel call    err      error             // set to non-nil by the first cancel call}

WithCancel(parent context) (ctx Context, cancel CancelFunc)
1. 通过函数WithCancel,生成了cancelCtx的实例,但是这个函数的返回值是Context.所以cancelCtx被赋值给Context后,对白只能暴露出Context的方法.
2. .cancelCtx实现了Context的Done方法.Done可以判断这个context是否被取消. WithCancel返回了一个cancelFunc,通过cancelFunc可以取消这个context,以及这个context的子context.

timerCtx类

type timerCtx struct {    cancelCtx    timer *time.Timer // Under cancelCtx.mu.    deadline time.Time}

这个类组合了cancelCtx.这个类是在cancelCtx的基础上,扩展了定时器功能.通过定时器,可以自动的去取消context.
1. 可以通过WithDeadline与WithTimeout来创建timerCtx实例,与WithCancel一样,这两个函数的返回值也是Context.

WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)

WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)

WithTimeout是对WithDeadline的更进一层封装.WithDeadline是设定具体的到日时间戳,而WithTimeout是在当前时间的基础上加上一个值,得到到期时间戳,接着调用了WithDeadline.

valueCtx类

type valueCtx struct {    Context    key, val interface{}}

WithValue(parent Context, key, val interface{}) Context

通过这个函数来创建valueCtx的实例.通过这个函数创建出来的Context,只能操作Value.但是可以通过父级context操作是否关闭当前的context.

总结

context类似于一个家族图谱.一层一层的继承.

0 0
原创粉丝点击