Go学习笔记—标准库Context
标准库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()
}
总结流程如下:
- 创建一个Context根对象 (通过Background或TODO创建)
- 包装上一步的Context对象,并加入特有功能 (通过WithCancel,WithTimeout,WithDeadline,WithValue创建)
- 将上一步创建的对象作为实参传递给后续启动的并发函数(一般作为其第一个参数),每个并发函数可以继续使用包装函数对传进来的Context对象进行包装,添加自己所需要的功能。
- 顶端的goroutine在超时后调用cancel退出通知函数,通知后面的所有goroutine释放资源。
- 后面的goroutine通过select监听Context.Done()返回的chan,及时相应前端goroutine的退出通知,释放资源。
Go学习笔记—标准库Context相关推荐
- go学习笔记-标准库
标准库 名称 摘要 archive tar tar包实现了tar格式压缩文件的存取.zip zip包提供了zip档案文件的读写服务. bufio bufio 包实现了带缓存的I/O操作. builti ...
- Linux学习笔记-标准库中的管道操作
目录 理论 例子 理论 stdio.h里面有标志库管道操作 FILE *popen(const char* cmdstring, const char *type);返回值:成功返回文件指针,出错返回 ...
- STM32 HAL库学习笔记1-HAL库简介
STM32 HAL库学习笔记1-HAL库简介 HAL库 SPL 库 和 HAL 库两者相互独立,互不兼容.几种库的比较如下 目前几种库对不同芯片的支持情况如下 ST 中文官网上有一篇<关于ST库 ...
- 一文搞懂Go标准库context包
"Gopher部落"星球双11现金优惠,点击链接领劵 https://t.zsxq.com/078E1QTjM 立减88元. 自从context包在Go 1.7版本[1]加入Go ...
- Go标准库Context
Go标准库Context 目录 为什么需要Context Context初始 Context接口 With系列函数 1. 为什么需要Context 在 Go http包的Server中,每一个请求在都 ...
- 如何系统的自学python 知乎-应该怎样系统的学习Python标准库?
先放个牛逼的学习资料:Python 3 Module of the Week,中文名<每周一个 Python 3 模块>.作者几乎实践了一遍全部标准库,并为每一个 API 补充了一段代码示 ...
- C++11学习笔记-----线程库std::thread
在以前,要想在C++程序中使用线程,需要调用操作系统提供的线程库,比如linux下的<pthread.h>.但毕竟是底层的C函数库,没有什么抽象封装可言,仅仅透露着一种简单,暴力美 C++ ...
- 如何系统的自学python-应该怎样系统的学习Python标准库?
先放个牛逼的学习资料:Python 3 Module of the Week,中文名<每周一个 Python 3 模块>.作者几乎实践了一遍全部标准库,并为每一个 API 补充了一段代码示 ...
- android jackson xml,[Android学习笔记]jackson库的使用
Jackson库一般用于序列化和反序列化操作,通常会涉及到的操作是: 1. Java Object -> Json String 2. Java Object -> Xml String ...
最新文章
- 桥接模式(Bridge)
- CSS解决高度自适应问题
- Java学习_day008面向对象(OOP):对象和类
- 【计算理论】计算复杂性 ( 证明团问题是 NP 完全问题 )
- Android源码分析-全面理解Context
- communication for making more gains or simply a leisure?
- boost::advance用法的测试程序
- 使用Azure DevOps持续集成GitHub项目
- MySQL数据库模式_SQL模式
- 李开复:21世纪7种人才最抢手
- 有关计算机组成原理知识的论文,关于计算机组成原理的论文_计算机组成原理_图灵机的组成...
- 最近重构公司消息服务的架构设计
- mysql的启动 两种方式
- ubuntu服务器上提示 To run a command as administrator (user “root“), use “sudo <command>“. See “ 解决方案
- 用html5制作机柜,基于HTML5 Canvas 点击添加 2D 3D 机柜模型
- krb5安装包 linux_Linux:krb5
- zabbix3.4 监控mysql 数据库连接数
- 微信小程序倒计时组件
- 苹果 / Apple iCloud 教育版 200GB 云盘账号自助注册教程
- 套件端口 群晖_群晖NAS的各种端口
热门文章
- RabbitMQ 延迟队列,消息延迟推送
- RH131 网络配置
- [Python3]Python面向对象的程序设计
- Android新闻案例clientserver达到,完全自己的新闻节目平台
- Android面试,BroadCastReceiver的两种注册方式的异同
- [转] C# 路径(目录)
- Omap3530 的GPIO中断设置
- 浅谈PROFINET IO通信的实时性
- 机器学习——人工神经网络之BP算法编程(python二分类数据集:马疝病数据集)
- matlab simulink笔记08——from workspace和from file模块的区别