golang context接口类型方法介绍

 更新时间:2023年09月27日 10:33:00   作者:lincoln_hlf1  
这篇文章主要为大家介绍了golang context接口类型方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

摘要

在很多的 Go 开源框架里,我们经常能看到 context 的身影,它的使用场景有很多,像超时通知,取消通知都用到了 context。今天我们就来好好的认识一下它,看看 context 的相关知识和底层原理。

context 介绍

context 从它的字面量就可以看出来,是用来传递信息的。当然,这种传递并不仅仅是将数据塞给被调用者,它还能进行链式的传递,通过保存父子 context 关系,不断的迭代遍历来获取数据。

除此之外,context 还能进行链式的传播 channel 信号

我们知道 channel 是用来做 goroutine 通信使用的。这就使得 goroutine 之间能够进行链式的信号通知了,进而达到自上而下的通知效果。

例如通知所有跟 context 有血缘关系的 goroutine 进行取消动作。

Context 接口

在 Go 里并没有直接为我们提供一个统一的 context 对象,而是设计了一个接口类型的 Context。然后在这些接口上来实现了几种具体类型的 context。

这样的好处就是我们只要根据开放出来的接口定义,也能够实现属于自己的 context,进而跟官方的 context 一起配合使用。

在分析官方的几种 context 之前,我们先来看看 context 要求实现的几个接口:

  • Deadline() (deadline time.Time, ok bool)
  • Done() <-chan struct{}
  • Err() error
  • Value(key interface{}) interface{}

其中:

Deadline() 表示如果有截止时间的话,得返回对应 deadline 时间;如果没有,则 ok 的值为 false。

Done() 表示关于 channel 的数据通信,而且它的数据类型是 struct{},一个空结构体,因此在 Go 里都是直接通过 close channel 来进行通知的,不会涉及具体数据传输。

Err() 返回的是一个错误 error,如果上面的 Done() 的 channel 没被 close,则 error 为 nil;如果 channel 已被 close,则 error 将会返回 close 的原因,比如超时或手动取消。

Value() 则是用来存储具体数据的方法。

Context 类型

简单的看过 Context 接口之后,我们来看看官方的 context 类型。主要有四种,分别是 emptyCtxcancelCtxtimerCtxvalueCtx

  • emptyCtx:空的 context,实现了上面的 4 个接口,但都是直接 return 默认值,没有具体功能代码。
  • cancelCtx:用来取消通知用的 context
  • timerCtx:用来超时通知用的 context
  • valueCtx:用来传值的 context

其中:
emptyCtx 表示什么都没有的 context,一般用作最初始的 context,作为父 context 使用。像我们常见的 context.Background()返回的就是 emptyCtx。

其他类型的创建方法如下:

  • WithCancel 方法创建的是 cancelCtx 类型的 context。
  • WithDeadline 方法创建的是 timerCtx 类型的 context。
  • WithValue 方法创建的是 valueCtx 类型的 context。

上面三个方法在创建的时候都会要求传 parent context 进来,以此达到链式传递信息的目的。

Context 源码

context 的源码在 src/context/context.go 里,相信大家仔细研究,也能看到上面介绍的几个 context 对象。这边简单解释下 cancelCtxtimerCtxvalueCtx 的核心流程。

1)cancelCtx 、timerCtx(用来通知用的 context)

cancelCtx 、timerCtx 在创建的时候都会调用 propagateCancel方法,将当前的 context 挂在 父 context 下。

接着在 Done() 方法里返回了对应的 channel,让调用者能够监听 channel 信号。

当要执行取消动作时,会通过 cancel 方法关闭 channel,来达到通知 goroutine 的目的。

在 channel 关闭的同时也会对子 context 调用 cancel 方法,直到没有子 context。

cancelCtx 和 timerCtxt 不同之处就在于 cancelCtx 是手动调用 cancel 方法来触发取消通知;

而 timerCtxt 则通过 AfterFunc 超时时间来自动触发 cancel 方法。

2)valueCtx(用来传值的 context)

valueCtx 通过 key-value 形式来存储数据,当找不到 key 时,就会到 父 context 里查找,直到没有父 context:

func (c *valueCtx) Value(key interface{}) interface{} {
    if c.key == key {
        return c.val
    }
    return c.Context.Value(key) // 到父 context 里查找
}

context 注意事项

最后我们来看看在使用 context 时的几个注意事项:

  • context 的 Done() 方法往往需要配合 select {} 使用,以监听退出。
  • 尽量通过函数参数来暴露 context,不要在自定义结构体里包含它。
  • WithValue 类型的 context 应该尽量存储一些全局的 data,而不要存储一些可有可无的局部 data。
  • context 是并发安全的。
  • 一旦 context 执行取消动作,所有派生的 context 都会触发取消。

以上就是golang context接口类型方法介绍的详细内容,更多关于golang context接口类型的资料请关注脚本之家其它相关文章!

相关文章

  • 一文带你了解Go语言中函数设计的实践示例

    一文带你了解Go语言中函数设计的实践示例

    良好设计的函数具有清晰的职责和逻辑结构,提供准确的命名和适当的参数控制,下面我们将一一描述函数设计时能够遵循的最佳实践,希望对大家有所帮助
    2023-06-06
  • Golang编程实现删除字符串中出现次数最少字符的方法

    Golang编程实现删除字符串中出现次数最少字符的方法

    这篇文章主要介绍了Golang编程实现删除字符串中出现次数最少字符的方法,涉及Go语言字符串遍历与运算相关操作技巧,需要的朋友可以参考下
    2017-01-01
  • Go  iota 常量基本语法介绍

    Go  iota 常量基本语法介绍

    这篇文章主要介绍了Go 为什么要设计 iota 常量,我们介绍了 Go 中 iota 的基本语法。同时基于历史资料针对 iota 到底是什么,为什么要这么叫,又有什么用进行了一番研究,需要的朋友可以参考下
    2022-06-06
  • Go语言中动态调用不同签名的函数的实现

    Go语言中动态调用不同签名的函数的实现

    本文主要介绍了Go语言中动态调用不同签名的函数的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-05-05
  • Go语言线程安全之互斥锁与读写锁

    Go语言线程安全之互斥锁与读写锁

    这篇文章主要介绍了Go语言线程安全之互斥锁与读写锁,互斥锁是为了并发的安全,在多个goroutine共同工作的时候,对于共享的数据十分不安全,而读写锁效率革命,使用锁的时候,安全与效率往往需要互相转换,下文详细内容,需要的小伙伴可以参考一下
    2022-02-02
  • golang 打印error的堆栈信息操作

    golang 打印error的堆栈信息操作

    这篇文章主要介绍了golang 打印error的堆栈信息操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05
  • 浅谈Go中数字转换字符串的正确姿势

    浅谈Go中数字转换字符串的正确姿势

    这篇文章主要介绍了浅谈Go中数字转换字符串的正确姿势,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • Go语言开发发送Get和Post请求的示例

    Go语言开发发送Get和Post请求的示例

    这篇文章主要介绍了Go语言开发发送Get和Post请求的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • 实时通信的服务器推送机制 EventSource(SSE) 简介附go实现示例代码

    实时通信的服务器推送机制 EventSource(SSE) 简介附go实现示例代码

    EventSource是一种非常有用的 API,适用于许多实时应用场景,它提供了一种简单而可靠的方式来建立服务器推送连接,并实现实时更新和通知,这篇文章主要介绍了实时通信的服务器推送机制 EventSource(SSE)简介附go实现示例,需要的朋友可以参考下
    2024-03-03
  • golang gorm的Callbacks事务回滚对象操作示例

    golang gorm的Callbacks事务回滚对象操作示例

    这篇文章主要为大家介绍了golang gorm的Callbacks事务回滚对象操作示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04

最新评论