您现在的位置是:首页 >技术教程 >【go】context作用以及源码分析网站首页技术教程

【go】context作用以及源码分析

CCSU__LRF 2024-06-14 17:17:09
简介【go】context作用以及源码分析

context是什么?

context是在go中在goroutine之间传递特定值,取消信号和截止时间的机制

context 接口定义 :

type Context interface {
    Deadline() (deadline time.Time, ok bool)
    Done() <-chan struct{}
    Err() error
    Value(key interface{}) interface{}
}
  1. Deadline方法用于获取Context的截止时间,如果没有设置截止时间则返回false。
  2. Done方法用于获取一个只读的channel,当Context被取消或者到达截止时间时,该channel会被关闭。
  3. Err方法用于获取Context的错误信息,如果Context未被取消则返回nil。
  4. Value方法用于获取Context中指定键的值,如果键不存在则返回nil。

context实现类型

Context接口的实现主要有两种类型:cancelCtx和timerCtx

cancelCtx

type cancelCtx struct {
    Context // 嵌入Context接口
    mu sync.Mutex // Mutex锁,用于保证并发安全性
    done chan struct{} // 一个只读的channel,用于通知Context已经被取消
    err error // Context的错误信息
}

timerCtx

type timerCtx struct {
    cancelCtx // 嵌入cancelCtx结构体
    deadline time.Time // 截止时间
    timer *time.Timer // 定时器
}

Context的创建

通过WithCancel、WithDeadline、WithTimeout和WithValue等函数创建。这些函数会返回一个新的Context和一个取消函数,可以用于取消Context的操作

WithCancel函数

WithCancel函数用于创建一个基础的Context实现,它包含了一个父级Context、一个取消函数cancel和一个只读的channel done。当使用cancel函数,会关闭done channel并且停止所有goroutine运行

func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
    c := newCancelCtx(parent)
    propagateCancel(parent, &c)
    return &c, func() { c.cancel(true, Canceled) }
}

WithDeadline函数

WithDeadline函数和WithTimeout函数用于创建一个带有截止时间的Context实现。当到达截止时间时,会自动取消Context,并关闭done channel。

func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
    c := &timerCtx{
        cancelCtx: newCancelCtx(parent),
        deadline:  deadline,
    }
    propagateCancel(parent, c)
    d := c.deadline.Sub(time.Now())
    if d <= 0 {
        c.cancel(true, DeadlineExceeded)
        return c, func() { c.cancel(true, Canceled) }
    }
    c.timer = time.AfterFunc(d, func() {
        c.cancel(true, DeadlineExceeded)
    })
    return c, func() { c.cancel(true, Canceled) }
}

func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
    return WithDeadline(parent, time.Now().Add(timeout))
}

WithValue函数

用于创建一个包含指定键值对的Context实现。这些键值对可以在多个goroutine之间传递信息。

func WithValue(parent Context, key, val interface{}) Context {
    if key == nil {
        panic("nil key")
    }
    if val == nil {
        panic("nil value")
    }
    return &valueCtx{parent, key, val}
}
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。