标准库Context

​ 由于goroutine没有父子关系,多个goroutine都是被平行的调度,所以在拉起多个goroutine后,程序的执行模型并没有维护树状结构的goroutine树,所以无法靠语法层面,通知树中所有goroutine退出。context库就是为了解决这个问题而被引入,目的:

(1) 退出通知机制:通知可以传递给整个goroutine调用树上的每一个goroutine

(2) 传递数据:数据可以传递给goroutine调用树上的每一个goroutine

1. context—基础数据结构

——构造取消树根节点对象的两个函数

func Background() Context 构造根节点,用作WithConcel的实参
func Todo() Context

——构建不同功能的Context对象

​ 这些方法都有一个参数parent,即在goroutine调用链中,每层都对Context实例包装自己所需的功能,并传递到下一层。

func WithCancel(parent Context) (ctx Context, cancel CancelFunc) 带有退出通知的Context对象
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) 带有超时通知的Context对象
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) 带有超时通知的Context对象
func WithValue(parent Context, key, value interface{}) Context 能够传递数据的Context对象
2. context—用例

ctxa.children——>ctxb、ctxb.children——>ctxc

  • ctxa 创建时:&cancelCtx{Context: new(emptyCtx)}
  • ctxb 创建时: &timerCtx{cancelCtx: ctxa deadline:tm} 同时出发ctxa,在children中加入ctxb
  • ctxc 创建时:&cancelCtx{Context: mc} 同时通过mc.Context找到ctxb,通过ctxb.cancelCtx找到ctxa,在ctxa的children中加入ctxc
type selfcontext struct {context.Context
}func work(ctx context.Context, name string) { //一个子任务,参数包含上下文信息与子任务名for {select {case <-ctx.Done(): //从上下文接收到结束信息fmt.Printf("%s get msg to cancel\n", name)returndefault:fmt.Printf("%s is running\n", name)time.Sleep(1 * time.Second)}}
}func workWithValue(ctx context.Context, name string) { //一个子任务,参数包含带值的上下文信息与子任务名for {select {case <-ctx.Done(): //从上下文接收到结束信息fmt.Printf("%s get msg to cancel\n", name)returndefault:value := ctx.Value("key").(string) //获取上下文中存储的key值fmt.Printf("%s is running and value is %s\n", name, value)time.Sleep(1 * time.Second)}}
}func ContextTest() {//使用background构建一个WithCancel类型的上下文ctxa, cancel := context.WithCancel(context.Background())go work(ctxa, "work1") //在此上下文,开启一个goroutine//使用ctxa构建一个WithDeadline类型的上下文tm := time.Now().Add(3 * time.Second)ctxb, _ := context.WithDeadline(ctxa, tm)go work(ctxb, "work2") //在此上下文,开启一个goroutine//使用ctxb构建一个WithValue类型的上下文mc := selfcontext{ctxb}ctxc := context.WithValue(mc, "key", "i am work3")go workWithValue(ctxc, "work3") //在此上下文,开启一个goroutinetime.Sleep(10 * time.Second) //经过10s,由于ctxc,ctxb都包含Deadline上下文,所以都已经超时停止//显示调用wordk1的cancal()方法,结束work1cancel()
}

总结流程如下:

  1. 创建一个Context根对象 (通过Background或TODO创建)
  2. 包装上一步的Context对象,并加入特有功能 (通过WithCancel,WithTimeout,WithDeadline,WithValue创建)
  3. 将上一步创建的对象作为实参传递给后续启动的并发函数(一般作为其第一个参数),每个并发函数可以继续使用包装函数对传进来的Context对象进行包装,添加自己所需要的功能。
  4. 顶端的goroutine在超时后调用cancel退出通知函数,通知后面的所有goroutine释放资源。
  5. 后面的goroutine通过select监听Context.Done()返回的chan,及时相应前端goroutine的退出通知,释放资源。

Go学习笔记—标准库Context相关推荐

  1. go学习笔记-标准库

    标准库 名称 摘要 archive tar tar包实现了tar格式压缩文件的存取.zip zip包提供了zip档案文件的读写服务. bufio bufio 包实现了带缓存的I/O操作. builti ...

  2. Linux学习笔记-标准库中的管道操作

    目录 理论 例子 理论 stdio.h里面有标志库管道操作 FILE *popen(const char* cmdstring, const char *type);返回值:成功返回文件指针,出错返回 ...

  3. STM32 HAL库学习笔记1-HAL库简介

    STM32 HAL库学习笔记1-HAL库简介 HAL库 SPL 库 和 HAL 库两者相互独立,互不兼容.几种库的比较如下 目前几种库对不同芯片的支持情况如下 ST 中文官网上有一篇<关于ST库 ...

  4. 一文搞懂Go标准库context包

    "Gopher部落"星球双11现金优惠,点击链接领劵 https://t.zsxq.com/078E1QTjM  立减88元. 自从context包在Go 1.7版本[1]加入Go ...

  5. Go标准库Context

    Go标准库Context 目录 为什么需要Context Context初始 Context接口 With系列函数 1. 为什么需要Context 在 Go http包的Server中,每一个请求在都 ...

  6. 如何系统的自学python 知乎-应该怎样系统的学习Python标准库?

    先放个牛逼的学习资料:Python 3 Module of the Week,中文名<每周一个 Python 3 模块>.作者几乎实践了一遍全部标准库,并为每一个 API 补充了一段代码示 ...

  7. C++11学习笔记-----线程库std::thread

    在以前,要想在C++程序中使用线程,需要调用操作系统提供的线程库,比如linux下的<pthread.h>.但毕竟是底层的C函数库,没有什么抽象封装可言,仅仅透露着一种简单,暴力美 C++ ...

  8. 如何系统的自学python-应该怎样系统的学习Python标准库?

    先放个牛逼的学习资料:Python 3 Module of the Week,中文名<每周一个 Python 3 模块>.作者几乎实践了一遍全部标准库,并为每一个 API 补充了一段代码示 ...

  9. android jackson xml,[Android学习笔记]jackson库的使用

    Jackson库一般用于序列化和反序列化操作,通常会涉及到的操作是: 1. Java Object -> Json String 2. Java Object -> Xml String ...

最新文章

  1. 桥接模式(Bridge)
  2. CSS解决高度自适应问题
  3. Java学习_day008面向对象(OOP):对象和类
  4. 【计算理论】计算复杂性 ( 证明团问题是 NP 完全问题 )
  5. Android源码分析-全面理解Context
  6. communication for making more gains or simply a leisure?
  7. boost::advance用法的测试程序
  8. 使用Azure DevOps持续集成GitHub项目
  9. MySQL数据库模式_SQL模式
  10. 李开复:21世纪7种人才最抢手
  11. 有关计算机组成原理知识的论文,关于计算机组成原理的论文_计算机组成原理_图灵机的组成...
  12. 最近重构公司消息服务的架构设计
  13. mysql的启动 两种方式
  14. ubuntu服务器上提示 To run a command as administrator (user “root“), use “sudo <command>“. See “ 解决方案
  15. 用html5制作机柜,基于HTML5 Canvas 点击添加 2D 3D 机柜模型
  16. krb5安装包 linux_Linux:krb5
  17. zabbix3.4 监控mysql 数据库连接数
  18. 微信小程序倒计时组件
  19. 苹果 / Apple iCloud 教育版 200GB 云盘账号自助注册教程
  20. 套件端口 群晖_群晖NAS的各种端口

热门文章

  1. RabbitMQ 延迟队列,消息延迟推送
  2. RH131 网络配置
  3. [Python3]Python面向对象的程序设计
  4. Android新闻案例clientserver达到,完全自己的新闻节目平台
  5. Android面试,BroadCastReceiver的两种注册方式的异同
  6. [转] C# 路径(目录)
  7. Omap3530 的GPIO中断设置
  8. 浅谈PROFINET IO通信的实时性
  9. 机器学习——人工神经网络之BP算法编程(python二分类数据集:马疝病数据集)
  10. matlab simulink笔记08——from workspace和from file模块的区别