context使用
1. 概述
go语言中goroutine之间的关联关系,缺乏维护,在erlang中有专门的机制来保障新开协程的生命周期,在go语言中,只能通过channel + select来实现,但不够直观,很绕。
Context 通常被译作 上下文 ,它是一个比较抽象的概念,一般理解为程序单元的一个运行状态、现场、快照。上下上下则是存在上下层的传递, 上 会把内容传递给 下 。
在Go语言中,程序单元也就指的是Goroutine。context 包不仅实现了在程序单元之间共享状态变量的方法,同时能通过简单的方法,使我们在被调用程序单元的外部,通过设置ctx变量值,将过期或撤销信号传递给被调用的程序单元。
在go服务器中(http服务器),对于每个请求的request都是在单独的goroutine中进行的,处理一个request也可能涉及多个goroutine之间的交互, 使用context可以使开发者方便地在这些goroutine里传递request相关的数据、取消goroutine的signal或截止时间
Done 方法在Context被取消或超时时返回一个close的channel,close的channel可以作为广播通知,告诉给context相关的函数要停止当前工作然后返回。
当一个父operation启动一个goroutine用于子operation,这些子operation不能够取消父operation。下面描述的WithCancel函数提供一种方式可以取消新创建的Context.
Context可以安全的被多个goroutine使用。开发者可以把一个Context传递给任意多个goroutine然后cancel这个context的时候就能够通知到所有的goroutine。
Err方法返回context为什么被取消。
Deadline返回context何时会超时。
Value返回context相关的数据。
需要注意的就是 调用CancelFunc会取消child以及child生成的context,取出父context对这个child的引用,停止相关的计数器
实战:
- context.Background 只应用在最高等级,作为所有派生 context 的根。
- context.TODO 应用在不确定要使用什么的地方,或者当前函数以后会更新以便使用 context。
- context 取消是建议性的,这些函数可能需要一些时间来清理和退出。
- context.Value 应该很少使用,它不应该被用来传递可选参数。这使得 API 隐式的并且可以引起错误。取而代之的是,这些值应该作为参数传递。
- 不要将 context 存储在结构中,要在函数中显式传递它们,最好是作为第一个参数。
- 永远不要传递不存在的 context 。相反,如果您不确定使用什么,使用一个 ToDo context。
- Context 结构没有取消方法,因为只有派生 context 的函数才可以取消 context。
参考示例1:
package main import (
"context"
"log"
"os"
"time"
) var logg *log.Logger func someHandler() {
ctx, cancel := context.WithCancel(context.Background())
go doStuff(ctx) //10秒后取消doStuff
time.Sleep(10 * time.Second)
cancel() } //每1秒work一下,同时会判断ctx是否被取消了,如果是就退出
func doStuff(ctx context.Context) {
for {
time.Sleep(1 * time.Second)
select {
case <-ctx.Done():
logg.Printf("done")
return
default:
logg.Printf("work")
}
}
} func main() {
logg = log.New(os.Stdout, "", log.Ltime)
someHandler()
logg.Printf("down")
time.Sleep(10 * time.Second)
}
输出
18:00:17 work
18:00:18 work
18:00:19 work
18:00:20 work
18:00:21 work
18:00:22 work
18:00:23 work
18:00:24 work
18:00:25 work
18:00:26 down
18:00:26 done
参考示例2:
package main import (
"context"
"log"
"os"
"time"
) var logg *log.Logger func doTimeOutStuff(ctx context.Context) {
for {
time.Sleep(1 * time.Second) if deadline, ok := ctx.Deadline(); ok { //设置了deadl
logg.Printf("deadline set")
if time.Now().After(deadline) {
logg.Printf(ctx.Err().Error())
return
} } select {
case <-ctx.Done():
logg.Printf("done")
return
default:
logg.Printf("work")
}
}
} func timeoutHandler() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
// ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second))
go doTimeOutStuff(ctx)
// go doStuff(ctx) time.Sleep(10 * time.Second) cancel() } func main() {
logg = log.New(os.Stdout, "", log.Ltime)
timeoutHandler()
logg.Printf("down")
time.Sleep(10 * time.Second)
}
输出:
18:04:37 deadline set
18:04:37 work
18:04:38 deadline set
18:04:38 work
18:04:39 deadline set
18:04:39 work
18:04:40 deadline set
18:04:40 work
18:04:41 deadline set
18:04:41 context deadline exceeded
18:04:46 down
参考链接:
https://studygolang.com/articles/12566
https://www.cnblogs.com/zhangboyu/p/7456606.html
https://studygolang.com/articles/13866?fr=sidebar
context使用的更多相关文章
- Javascript 的执行环境(execution context)和作用域(scope)及垃圾回收
执行环境有全局执行环境和函数执行环境之分,每次进入一个新执行环境,都会创建一个搜索变量和函数的作用域链.函数的局部环境不仅有权访问函数作用于中的变量,而且可以访问其外部环境,直到全局环境.全局执行环境 ...
- spring源码分析之<context:property-placeholder/>和<property-override/>
在一个spring xml配置文件中,NamespaceHandler是DefaultBeanDefinitionDocumentReader用来处理自定义命名空间的基础接口.其层次结构如下: < ...
- spring源码分析之context
重点类: 1.ApplicationContext是核心接口,它为一个应用提供了环境配置.当应用在运行时ApplicationContext是只读的,但你可以在该接口的实现中来支持reload功能. ...
- CSS——关于z-index及层叠上下文(stacking context)
以下内容根据CSS规范翻译. z-index 'z-index'Value: auto | <integer> | inheritInitial: autoApplies to: posi ...
- Tomcat启动报错org.springframework.web.context.ContextLoaderListener类配置错误——SHH框架
SHH框架工程,Tomcat启动报错org.springframework.web.context.ContextLoaderListener类配置错误 1.查看配置文件web.xml中是否配置.or ...
- mono for android Listview 里面按钮 view Button click 注册方法 并且传值给其他Activity 主要是context
需求:为Listview的Item里面的按钮Button添加一个事件,单击按钮时通过事件传值并跳转到新的页面. 环境:mono 效果: 布局代码 主布局 <?xml version=" ...
- Javascript的“上下文”(context)
一:JavaScript中的“上下文“指的是什么 百科中这样定义: 上下文是从英文context翻译过来,指的是一种环境. 在软件工程中,上下文是一种属性的有序序列,它们为驻留在环境内的对象定义环境. ...
- spring源码分析之<context:component-scan/>vs<annotation-config/>
1.<context:annotation-config/> xsd中说明: <xsd:element name="annotation-config"> ...
- 【Android】 context.getSystemService()浅析
同事在进行code review的时候问到我context中的getSystemService方法在哪实现的,他看到了一个ClipBoardManager来进行剪切板存储数据的工具方法中用到了cont ...
- context:component-scan" 的前缀 "context" 未绑定。
SpElUtilTest.testSpELLiteralExpressiontestSpELLiteralExpression(cn.zr.spring.spel.SpElUtilTest)org.s ...
随机推荐
- SSM 记录
前言:本过程从0开始,先是导入最核心的jar包,然后随着ssm中的功能实现,打包===>启动===>报错,一步步解决问题,增加额外的必须的jar包来熟悉ssm 1.导包(核心包) myba ...
- linux 服务器时间同步
1 12 * * * .usr/sbin/nttpdate pool.ntp.org 分时 天 周 月 定时更同步 crontab -e 先查看是否安装 ntp这个包 没有安装的话 yum-y ...
- SharePoint列表模板(.stp)
背景:在sharepoint中,我们经常使用SharePoint Designer定制列表的新建.编辑.查看页面,当我们在开发环境定制好了的时候,怎么才能将定制的列表移到正式环境. 实现 ...
- Spring框架学习之--搭建spring框架
此文介绍搭建一个最最简单的spring框架的步骤 一.创建一个maven项目 二.在pom.xml文件中添加依赖导入spring框架运行需要的相关jar包 注意:在引入jar包之后会出现org.jun ...
- 修改文件MD5值
1.查看文件的MD5值 (1)下载MD5Checker http://getmd5checker.com/download.html 或者 链接: https://pan.baidu.com/s/1e ...
- Mysql+keepalived双主
搭建环境说明: master1:192.168.175.210 主 master2:192.168.175.211 备 keepalived的vip: 192.168.175.11(注意这是虚拟IP, ...
- java的智能提示无法打开
第一步:选中“window”->“preference” 第二步:选中“java”,并展开 第三步:选中“Editor”,并展开 第四步:选中“Content Assist”,在右侧 ...
- 解决Qt下ssl出错的办法
在使用 QNetworkAccessManager 时出现的ssl错误:qt.network.ssl: QSslSocket: cannot resolve SSL_set_psk_client_ca ...
- 关于MapReduce二次排序的一点解答
上一篇博客说明了怎么自定义Key,而且用了二次排序的例子来做测试,但没有详细的说明二次排序,这一篇说详细的说明二次排序,为了说明曾经一个思想的误区,特地做了一个3个字段的二次排序来说明.后面称其为“三 ...
- python数据类型值数字类型
1.bin()函数是将十进制数转换成二进制数 2.oct()函数将十进制数转换成八进制数 3.hex()函数将十进制数转换成十六进制 数 十六进制表示:0-9 a b c d e f 4.数字 ...