Golang Context 简介

前言

在写Golang程序调用各种第三方库的时候, 经常会传一个叫做Context的参数. 之前基本上见到接Context, 根本不管是干什么用的, 直接无脑context.Background().

但是, 传着传着就不免发生一些小疑问, 这个参数到底是干什么用的呢? 这么多库都在使用, 至少说明其是Golang中的一个共识, 一个基础元素. 除了context.Background()一定还有其他的值, 否则也不会作为参数来接收了.

用了这么久, 都不知道它的作用, 这实在有点说不过去了, 于是抽时间来好好研究研究contextGolang中的作用.

作用

Golang源码包中, context.go很贴心的给出来官网介绍的文章: https://blog.golang.org/context

Golang中, 协程被设计为非常方便且轻量的用户态线程, 鼓励我们使用协程来完成各种耗时的操作.

假设, 有一个处理请求Agoroutine, 其同时又启动了n个额外的goroutine来协助操作. 此时, 若请求 A被取消, 那么所有相关的资源都需要被释放, 所有处理该请求的goroutine都应该快速退出, 防止造成资源的浪费. 那么问题来了, parent是无法主动关闭子协程的, 如何通知子协程需要提前退出呢?

我想了想, 这不就是多协程之间的通信么, 这块我熟啊. 用锁, 用管道, 用什么都行, 只要将取消的消息群发给所有子协程就可以了, 随便列举几个方案:

  • 共享变量. 通过共享一个bool变量, 子协程定期检测变量值来判断是否需要退出
  • 管道. 子协程定期检测管道是否关闭来判断是否需要退出
  • 等等

没错了, Context就是干这个用的. 它提出来的主要目的, 就是提醒子协程该退出了. 而它实现的原理也是通过协程通信实现的, 只是在其上面封了一层, 以方便调用.

虽然Context在刚开始的时候只是为了封装子协程的退出提醒(只是我的猜测), 但是既然都加上下文了, 自然得带点上下文环境变量了. 其作用通过Context接口暴露的方法可窥见一二:

  • Deadline() (deadline time.Time, ok bool)
    • 返回工作的截止时间. (若没有, 则 ok=false)
  • Done() <-chan struct{}
    • 返回一个管道. 若从管道中可以读到数据, 说明任务被关闭了. (若不需要, 返回 nil)
    • 通常做法为在需要退出时将管道关闭.
  • Err() error
    • 返回任务被关闭的原因.
  • Value(key any) any
    • 返回上下文包含的环境变量

因此, Context其实只能够干两件事

  1. 通知子协程提前退出
  2. 携带环境变量

context 包

Golangcontext包除了测试文件, 仅contxt.go一个文件. 且, 将context.go文件中的注释和空行去掉之后, 整个文件代码仅318行(使用版本为 go 1.18), 称得上短小精悍了. 这里就不分析源码了, 感兴趣的自己看一下, 简单整理一些context包中包含的内容:

官方已实现的常用Context结构体, 均为私有结构体, 需要使用下方的方法生成, 官方仅实现了常用的几个实例, 这几个实例可组合使用, 若不能满足自己需求也可以自己实现:

名称作用
emptyCtx空的Context, 所有接口实现均为空实现. 既永远不会停止
cancelCtx可以被主动取消的Context. parent调用特定方法进行取消
timerCtx定时器, 在指定时间后取消
valueCtx永远不会停止, 用来传递上下文环境变量

context包中提供的公共方法, 我们通常调用的就是这些了, 可以看到, 官方提供的生成方法, 都是基于一个已有的context基础上进行生成, 也就是说我们在使用的时候可以进行组合, 将前一个生成的结果作为参数来生成下一个, 以获得拥有多种功能的context, 这个设计还是很巧妙的:

类型名称作用
方法Background返回一个emptyCtx实例
TODO返回一个emptyCtx实例.
官方推荐是, 当不知道应该用哪个的时候, 临时使用TODO
WithCancel在一个context的基础上, 生成一个可以取消的context.
两个context均可以执行取消的操作, 取决于哪个先发生
WithDeadline在一个context基础上, 生成一个特定时间关闭的context
WithTimeout在一个context基础上, 生成一个特定时长关闭的context
WithValue在一个context基础上, 生成一个拥有指定k-vcontext
变量Canceled定义好的取消文案
DeadlineExceeded定义好的取消文案. 时间到了

最后

最后, 在查看了Context内容之后, 有些个人的小疑问.

1. Context接口设计的过于臃肿

其实, Context并不需要保存k-v, 应用程序总是可以通过自己的方式将上下文在多个协程之间共享的.

并且, DeadlineDone方法是否有些臃肿? 其实子协程仅仅需要知道是否退出即可, 甚至于我觉得Context只需要实现这样一个方法就可以了:

IsCancel() (cancel bool, e err)

十分简洁, 只需要告诉子协程是否退出及原因不就可以了么?

当然, 也可能官方是出于其他我没有想到的原因考虑.

2. parent只能通知子协程退出, 但子协程什么时候退出parent是不知道的

如题, parent通过Context通知子协程退出后, 对于子协程是否退出是没有感知的. 现实中是否有这样的场景暂时没有想到, 不过应该会有吧.


原文链接: https://hujingnb.com/archives/825

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508344.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PHP获取Opcode及C源码

是什么 在开始之前, 必须要先介绍一下Opcode是什么. 众所周知, Java在执行的时候, 会将.java后缀的文件预先编译为.class字节码文件, JVM加载字节码文件进行解释执行. 而字节码文件存在的意义, 就是为了加速执行. 那么PHP的Opcode与之类似, 也是从.php文件到执行的过程中, 所…

PHP require/include 区别

前言 在PHP中, 载入文件可以选择使用require, 也可以使用include, 那么那他们有什么区别呢? 看了网上的一些文章, 说他们使用场景不同, require一般在文件开头引入文件, include一般在函数中动态引入文件. 但是我觉得并不是这么简单, require是作为语言结构(关键字)出现的, …

RESTful API规范

前言 我现在工作的公司是在毕业前实习的公司, 实习结束后直接转正, 因此也是我任职过的唯一一家公司. 在日常工作进行 HTTP 接口的开发时, 发现了一个疑惑, 只用到了POST和GET请求, 但我们知道 HTTP还有PUT/DELETE等等, 为什么不用呢? 并且, 接口的响应码也只有200, 接口是…

Golang 接口原理

问题 小提示, 若想直接查看原理, 可从接口原理开始查看. 有这样一段GO代码: func main() {var obj interface{}fmt.Printf("obj nil. %b\n", obj nil)type st struct{}var s *stobj sfmt.Printf("s nil. %b\n", s nil)fmt.Printf("obj nil. …

Docker kill 1无效

前言 我们在平常强制停用一个进程的时候, 会选择什么命令? 一般在测试使, 不考虑程序突然中断带来的影响, 直接使用kill -9 pid强制停止就行. 但是, 就在刚刚, 我启动了一个docker容器, 进入容器后执行命令kill -9 1没有任何效果??? 啊这, 为什么呀? 尝试 为了解释这个…

容器内存相关知识

这篇文章是我研究容器内存整理出的相关内容. 前后内容并没有上下文关系, 每个知识点都可以单独查看. 内存控制 使用这样的命令启动一个容器docker run -d -m 300M xxx. 可以限制容器使用的内存最大为300M. 那么docker是如何实现容器的内存限制呢? 其实是操作系统已经做好了…

三星识别文字_比亚迪电子助力三星Galaxy Note 10系列霸气首发!

三星有子初长成气宇轩昂 秀美俊逸减之一分则嫌柔增之一分则嫌赘2019年8月7日于纽约巴克莱发布Galaxy Note 10系列用简约 重构美三星Galaxy Note 10与Galaxy Note 10分别搭载了6.3英寸和6.8英寸的超感官全视曲面屏&#xff0c;均采用单摄挖孔屏&#xff0c;开孔位于屏幕正上方。…

lisp 设计盘形齿轮铣刀_机械设计基础——周转轮系传动比的计算

点击上方蓝色字体&#xff0c;关注我们15(视频来源于网络&#xff0c;仅供学习交流&#xff0c;侵权请联系删除)机械计重点学习指导机械原理全书重点提要轴的结构改错机械设计作业集01机械设计作业集02机械设计作业集答案机械原理作业集机械原理作业集答案轴的强度计算院校推荐…

b+树阶怎么确定_B站公布年度弹幕,这个排名我不太服气

也忘记了是从什么时候开始&#xff0c;B站开始公布自己的年度弹幕了&#xff0c;今年的年度弹幕排名前五的分别是&#xff1a;爷青回、武汉加油、有内味了、双厨狂喜、禁止套娃。话说今年真的是不容易啊&#xff0c;过年那段时间以及上半年不会忘记那一幕幕感人深邃的瞬间&…

css打印适应纸张_从生态平衡到打印机故障分析

生态平衡(ecological equilibrium)是指在一定时间内生态系统中的生物和环境之间、生物各个种群之间&#xff0c;通过能量流动、物质循环和信息传递&#xff0c;使它们相互之间达到高度适应、协调和统一的状态。也就是说当生态系统处于平衡状态时&#xff0c;系统内各组成成分之…

html5调用系统声音1s响一次_20款奔驰GLC260提车改柏林之声音响,音乐诉请,为爱发声!...

奔驰GLC车型在2020上半年可谓是风生水起&#xff0c;尤其是2020年1-5月份的豪华品牌SUV排名中&#xff0c;奔驰GLC车型以58982的销售量遥遥领先&#xff0c;同比增长了2%&#xff0c;奔驰GLC5月销量高达15275辆&#xff0c;再次打败老对手奥迪Q5L&#xff0c;夺得豪华SUV销量冠…

js排序的时间复杂度_冒泡排序最好时间复杂度为什么是O

展开全部冒泡排序的基本思想是&#xff0c;对相邻的元素进行两两比较&#xff0c;顺序相反则进行交换&#xff0c;这样&#xff0c;每一趟会e68a8462616964757a686964616f31333433616161将最小或最大的元素“浮”到顶端&#xff0c;最终达到完全有序代码实现在冒泡排序的过程中…

kotlin将对象转换为map_将网站转换为Photoshop文档

WebToLayers是一款能够帮助大家将网页转换成图像格式的软件&#xff0c;能够Web页面转换成PNG&#xff0c;JPG以及PSD格式的图片。当网页转换为PSD的时候&#xff0c;网页的各个要素都会自动转换为相应的图层&#xff0c;使得大家能够对PSD格式的网页进行设计与管理。WebToLaye…

centos更换网卡后怎么更新配置_CentOS安装

服务器使用的Linux操作系统都使用了CentOS来进行安装&#xff0c;CentOS是一个开源的Linux发行版&#xff0c;具有很好的稳定性和更多的可扩展行。为了能够正常使用Docker&#xff0c;我们将使用CentOS7及以上版本。​下载地址&#xff1a;https://www.centos.org/download/ ​…

串口485接法图_rs485接口接线怎样操作?

展开全部RS485采用差分62616964757a686964616fe58685e5aeb931333365633939信号负逻辑&#xff0c;2V&#xff5e;6V表示“0”&#xff0c;- 6V&#xff5e;- 2V表示“1”。RS485有两线制和四线制两种接线&#xff0c;四线制是全双工通讯方式&#xff0c;两线制是半双工通讯方式…

centos普通用户修改文件权限_Linux实战014:Centos创建用户并添加root授权

刚收到在腾讯云申请的云服务器8台&#xff0c;现在准备分配给不同项目组来使用。为了确保系统及账号的安全&#xff0c;root账号不能直接给到他们。因为root的权限太大&#xff0c;任何的误操作就可能导致系统异常或者数据丢失找不回来。而且我们这是生产环境&#xff0c;账号会…

mongodb 导出txt_(干货)前端实现导出excel的功能

前言 导出功能其实在开发过程中是很常见的,平时我们做导出功能的时候基本都是后台生成&#xff0c;我们直接只需要调一支接口后台把生成的文件放到服务器或者数据库mongodb中,如果是放到mongodb中的话,我们需要从mongodb中通过唯一生成的id去拿到文件,最后window.location.href…

1971旗舰cpu intel_CPU的历史

很多人都对电脑硬件有一点的了解&#xff0c;本人也算略懂一二&#xff0c;所以今天来为大家说说电脑的主要硬件之一––CPU(中央处理器)。那么我们知道世界上造CPU的公司主要就是Intel和AMD。其实仔细想想&#xff0c;CPU的主要成分是什么?是硅(Si)&#xff0c;硅从那里来&am…

文本显示变量_【RPA课堂】UiPath中的变量、数据类型和组件

自动化出现的那一天起&#xff0c;就有了各种各样的工具来满足自动化的需要。无论是用于windows桌面自动化的简单工具&#xff0c;还是用于企业自动化大量任务的工具&#xff0c;它们都有自己的功能。UiPath就是这样的工具&#xff0c;在本文中&#xff0c;我们介绍一些非常基本…

linux挂载cifs磁盘_CentOS7.4_1708挂载CIFS报错

CentOS7.41708操作系统&#xff0c;Windows_Server2012做1TB的网络共享磁盘(没有域)。今天在项目做软件加密的部署&#xff0c;现场环境是Vsphere虚拟化需要用CIFS共享来传输文件、软件等。CRT、Putty等工具的传输工具无法传输字符集&#xff01;CentOS操作系统终端界面无任务信…