golang 之 context包
概述
context是Go中广泛使用的程序包,由Google官方开发,在1.7版本引入。它用来简化在多个go routine传递上下文数据、(手动/超时)中止routine树等操作,比如,官方http包使用context传递请求的上下文数据,gRpc使用context来终止某个请求产生的routine树。每个Context应该视为只读的,通过WithCancel、WithDeadline、WithTimeout和WithValue函数可以基于现有的一个Context(称为父Context)派生出一个新的Context(称为子Context)。其中WithCancel、WithDeadline和WithTimeout函数除了返回一个派生的Context以外,还会返回一个与之关联CancelFunc类型的函数,用于关闭Context。通过调用CancelFunc来关闭关联的Context时,基于该Context所派生的Context也都会被关闭,并且会将自己从父Context中移除,停止和它相关的timer。
核心接口
type Context interface {
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{}
Err() error
Value(key interface{}) interface{}
}
根据如上接口显示对每个方法介绍
Done会返回一个channel,当该context被取消的时候,该channel会被关闭,同时对应的使用该context的routine也应该结束并返回。Context中的方法是协程安全的,这也就代表了在父routine中创建的context,可以传递给任意数量的routine并让他们同时访问。Deadline会返回一个超时时间,routine获得了超时时间后,可以对某些io操作设定超时时间。Value可以让routine共享一些数据,当然获得数据是协程安全的。
在请求处理的过程中,会调用各层的函数,每层的函数会创建自己的routine,是一个routine树。所以,context也应该反映并实现成一棵树。
创建context
在创建context时会通过context.Background函数的返回值是一个空的context,作为树的根结点。并且提供4个常用函数去创建其子节点。
func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
func WithValue(parent Context, key interface{}, val interface{}) Context
需要注意的是每个函数都会返回一个CancelFunc。调用CancelFunc对象将撤销对应的Context对象,这样父结点的所在的环境中,获得了撤销子节点context的权利,当触发某些条件时,可以调用CancelFunc对象来终止子结点树的所有routine。
我们在子集中可以通过 cxt.Done()是否为空来判断。
select {
case <-cxt.Done():
// do some cleaning and return
}
WithDeadline和WithTimeout比WithCancel多了一个时间参数,它指示context存活的最长时间。如果超过了过期时间,会自动撤销它的子context。所以context的生命期是由父context的routine和deadline共同决定的。
WithValue返回parent的一个副本,该副本保存了传入的key/value,而调用Context接口的Value(key)方法就可以得到val。注意在同一个context中设置key/value,若key相同,值会被覆盖。
示例
package main import (
"fmt"
"time"
"golang.org/x/net/context"
) func main() {
ctx, cancelFunc := context.WithTimeout(context.Background(), time.Second*5)
ctx = context.WithValue(ctx, "Test", "123456")
defer cancelFunc() if t, ok := ctx.Deadline(); ok {
fmt.Println(time.Now())
fmt.Println(t.String())
}
go func(ctx context.Context) {
fmt.Println(ctx.Value("Test"))
for {
select {
case <-ctx.Done():
fmt.Println(ctx.Err())
return
default:
continue
}
}
}(ctx)
time.Sleep(time.Second * 3)
}
golang 之 context包的更多相关文章
- golang中context包学习
摘要 go语言中goroutine之间的关联关系,缺乏维护,在erlang中有专门的机制来保障新开仟程的生命周期, 在go语言中,只能通过channel + select来实现,但不够直观,感觉很绕. ...
- golang中的context包
标准库的context包 从设计角度上来讲, golang的context包提供了一种父routine对子routine的管理功能. 我的这种理解虽然和网上各种文章中讲的不太一样, 但我认为基本上还是 ...
- Golang的Context介绍及其源码分析
简介 在Go服务中,对于每个请求,都会起一个协程去处理.在处理协程中,也会起很多协程去访问资源,比如数据库,比如RPC,这些协程还需要访问请求维度的一些信息比如说请求方的身份,授权信息等等.当一个请求 ...
- Golang context包解读
Context 通常被译作 上下文 ,一般理解为程序单元的一个运行状态.现场.快照,而翻译中 上下 又很好地诠释了其本质,上下上下则是存在上下层的传递, 上 会把内容传递给 下 . 在Go语言中,程序 ...
- Golang Context 包详解
Golang Context 包详解 0. 引言 在 Go 语言编写的服务器程序中,服务器通常要为每个 HTTP 请求创建一个 goroutine 以并发地处理业务.同时,这个 goroutine 也 ...
- golang context包
go context标准库 context包在Go1.7版本时加入到标准库中.其设计目标是给Golang提供一个标准接口来给其他任务发送取消信号和传递数据.其具体作用为: 可以通过context发送取 ...
- Golang之Context的使用
转载自:http://www.nljb.net/default/Golang%E4%B9%8BContext%E7%9A%84%E4%BD%BF%E7%94%A8/ 简介 在golang中的创建一个新 ...
- golang中Context的使用场景
golang中Context的使用场景 context在Go1.7之后就进入标准库中了.它主要的用处如果用一句话来说,是在于控制goroutine的生命周期.当一个计算任务被goroutine承接了之 ...
- 深入理解golang:Context
一.背景 在golang中,最主要的一个概念就是并发协程 goroutine,它只需用一个关键字 go 就可以开起一个协程,并运行. 一个单独的 goroutine运行,倒也没什么问题.如果是一个go ...
随机推荐
- 【luoguP2989】[USACO10MAR]对速度的需要Need For Speed
题目描述 最大化平均值 二分一个\(x\) \(check\): \(\frac{F+\sum_{i=1}^{n} X_{i} \times F_{i}}{M+\sum_{i=1}^{n} X_{i} ...
- (转载)如何在当前目录下快速打开cmd
很多时候我们需要打开命令行然后进入到相应目录进行一些操作. 常规的做法是: Win+R打开运行窗口 输入"cmd"回车打开命令行窗口 假如我们要进入的是D盘foo文件夹下的一个ba ...
- 关于window.getSelection
window.getSelection(),返回一个Selection对象,表示用户选择的文本范围或光标的当前位置. selection对象先来看下面两个selection结果:selection对象 ...
- pyqt(day1)
参考代码地址:https://github.com/cxinping/Pyqt5 pyqt在线帮助文档:https://www.riverbankcomputing.com/static/Docs/P ...
- 《微信小程序商城开发实战》唐磊,全网真实评价截图,不吹不黑,全部来自网友的真实评价
偶尔看了下网友的销量和评价,感觉还不错,因为市面上大多关于小程序的书籍可能写的不够全面,要么只是点到为止的大致罗列,要么就是只简单介绍一下小程序的 界面设计这块.这样很难给学习小程序开发的人一个完成的 ...
- Java虚拟机解释器与JIT编译器
一.JAVA编译相关概念 1.动态编译(dynamic compilation)指的是“在运行时进行编译”:与之相对的是事前编译(ahead-of-time compilation,简称AOT),也叫 ...
- SQLServer查看及设置最大连接数(转)
转自:https://blog.csdn.net/duanbeibei/article/details/86573840 很多时候自己本地开发会遇到 ,打开几个连接正常访问 之后就报错误,这时候需要调 ...
- 关于OpenGPU.org
今天是心情沉重的一天. OpenGPU.org,作为当年中国图形学界首屈一指的论坛,曾经创造过日访问破万的记录,而且汇聚了中国所有的图形行业的精英,大家畅所欲言,为整个中国图形学业界分享了无数宝贵的资 ...
- python网络编程 - tcp
网络编程 低级别的网络服务 高级别的网络服务 socket又称“套接字”,应用程序通过“套接字”向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯. tcp 传输控制协议(Tra ...
- {Redis}NOAUTH Authentication required. Linux.cenOS
问题 [root@VM_0_12_centos redis]# ./bin/redis-cli -p 6379 127.0.0.1:6379> INFO NOAUTH Authenticatio ...