0%

Golang系列(一)-context使用

go的context包详解,context中文翻译过来叫“上下文”,本篇文章讲一下它具体的作用是什么。你在什么情况下可以用到它。

引言

http server 常为每个请求创建一个 goroutine 以并发地处理请求,同时这个 goroutine 又会创建更多的 gotoutine 来访问数据库和缓存或RPC服务,当请求结束或被终止,能释放所有 gotoutine的资源。因此就需要一种机制,在goroutine之间传递信号消息。

简介

context 中文翻译过来叫”上下文“,常被用来 goroutine 之间传递信息和信号的。信息和信号包括截至时间(deadline),取消信号(cancellation signals) 以及跨边界需要往下传递的键值对信息。

特性

  • context的设计是可通过已有Context进行树型派生,已管理一组过程的生命周期。单Context是不可变的,但可以通过WithValue、WithCancel、WithTimeout方法进行派生并附加一些属性(键值、可取消、时限),以构建一组树型组织的context。
  • 当根 Context 结束时,所有由其派生出的 Context 也会被一并取消。也就是说,父 Context 的生命周期涵盖所有子 Context 的生命周期。

使用

创建根Context

context.Background() 创建一个空的Context(not nil), 常用作初始化创建根Context。

派生携带键值信息Context

context.WithValue(parentContext, key, value) 在父节点Context的基础上创建一个新的携带键值信息的的子节点Context。

派生可取消Context

context.WithCancel(parentContext) 在父节点Context的基础上创建一个新的可取消的子节点Context,返回新创建的子节点Context和取消方法cancelFunc。

派生有时间限制Context

context.WithTimeout(parentContext,timeout)在父节点Context的基础上创建新的有时间限制的子节点Context,返回新创建子节点Context和取消方法cancelFunc。超过时间限制后,该Conext会发送信号到Done通道,所有子节点检测到信号立即退出。

派生有截至时间Context

context.WithDeadline(parentContext, time)在父节点Context的基础上创建新的有截至时间的子节点Context,返回新创建子节点Context和取消方法cancelFunc。context.Timeout(parentContext,timeout)等价于context.Deadline(parentContext,time.Now().Add(timeout))

注意

  • Background 创建的根节点没有时限,也不能取消。
  • WithCancel、WithTimeout、WithDeadline方法是从父context派生出新的context,新的context受限与父context的生命周期。新context应注意在对应过程结束后及时cancel,以防止goroutine泄露。
  • 不能使用nil Context,尽管语法上允许。不知道使用什么值合适时,可以使用 context.TODO()