Go的 context 包的使用
文章目录
- 背景
- 简介
- 主要方法
- 获得顶级上下文
- 当前协程上下文的操作
- 创建下级协程的Context
- 场景示例
背景
在父子协程协作过程中, 父协程需要给子协程传递信息, 子协程依据父协程传递的信息来决定自己的操作.
这种需求下可以使用 context 包
简介
Context通常被称为上下文,在go中,上层的协程可以将context 传给下层的协程, 来实现协程之间的信息传递, 同时下层协程也可以将context 传给更下层的协程, 来形成一张树状图.
主要方法
获得顶级上下文
首先要获得最顶级协程使用的Context
func Background() Context
Background 方法一般创建根 Context 的时候。
func TODO() Context
TODO 方法,当不清楚使用哪个上下文时,可以使用 TODO 方法。
当前协程上下文的操作
针对 Context 可以执行如下操作.
Deadline() (deadline time.Time, ok bool)
Deadline 方法返回结果有两个,第一个是截止时间,到了这个截止时间,Context 会自动取消;第二个是一个 bool 类型的值,如果 Context 没有设置截止时间,第二个返回结果是 false,如果需要取消这个 Context,就需要调用取消函数。
Done() <-chan struct{}
Done 方法返回一个只读的 channel 对象,类型是 struct{},在 goroutine 中,如果 Done 方法返回的结果可以被读取,代表父 Context 调用了取消函数。
Err() error
Err 方法返回 Context 被取消的原因。
Value(key interface{}) interface{}
Value 方法返回此 Context 绑定的值。它是一个 kv 键值对,通过 key 获取对应 value 的值
创建下级协程的Context
我们要依据父级的协程的Context创建子级协程的Context
WithCancel(parent Context) (ctx Context, cancel CancelFunc)
WithCancel 方法,基于父 Context,接收一个父 Context 参数,生成一个新的子 Context,和一个 cancel 函数,用于取消 Context。
WithDeadline(parent Context, d time.Time) (Context, CancelFunc)
WithDeadline 方法,基于父 Context,接收一个父 Context 参数,和一个截止时间的参数,生成一个新的子 Context,和一个 cancel 函数,可以使用 cancel 函数取消 Context,也可以等到截止时间,自动取消 Context。
WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
WithTimeout 方法,基于父 Context,接收一个父 Context 参数,和一个超时时间的参数,生成一个新的子 Context,和一个 cancel 函数,可以使用 cancel 函数取消 Context,也可以等到超时时间,自动取消 Context。
WithValue(parent Context, key, val interface{}) Context
WithValue 方法,基于父 Context,生成一个新的子 Context,携带了一个 kv 键值对,一般用于传递上下文信息。
场景示例
公司下班, 要领导下班后, 员工才下班, 但是员工忍耐也是有限度的, 领导老是不下班, 员工就自己走了.
package mainimport ("context""fmt""time"
)var name stringfunc main() {// 顶级Conxt, 领导up_context := context.Background()// 创建领导的下级 员工的的Context, 员工就最多加班5秒, 超过5秒领导不下班. 员工就下班了ctx, cancle := context.WithTimeout(up_context, time.Second*5)go work(ctx, "小卡拉")// 父线程等待3秒, 领导加班3秒time.Sleep(time.Second * 3)fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "领导下班了!")// 领导下班调用cancle(), 取消员工的 Contextcancle()time.Sleep(time.Second * 5)
}func work(ctx context.Context, name string) {for {select {// 看看员工的 Context 还在不在case <-ctx.Done():fmt.Println(time.Now().Format("2006-01-02 15:04:05"), name, "下班!")returndefault:fmt.Println(time.Now().Format("2006-01-02 15:04:05"), name, "加班!。")time.Sleep(time.Second * 1)}}
}
上面的代码中up_context 是最顶级的 Context 是使用context.Background()创建出来的, 员工的 Context对象 ctx 则是使用最顶级的up_context 并且使用WithTimeout方法创建出来的, 表示如果5秒内不调用返回的 cancel 方法, 就会自动取消, 对应员工最多等待领导五秒. 上面的执行结果是:

可以看到, 领导就加班了3秒, 领导一下班, 员工就下班了.
如果领导加班7秒呢, 代码改成如下
package mainimport ("context""fmt""time"
)var name stringfunc main() {// 顶级Conxt, 领导up_context := context.Background()// 创建领导的下级 员工的的Context, 员工就最多加班5秒, 超过5秒领导不下班. 员工就下班了ctx, cancle := context.WithTimeout(up_context, time.Second*5)go work(ctx, "小卡拉")// 父线程等待7秒, 领导加班7秒time.Sleep(time.Second * 7)fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "领导下班了!")// 领导下班调用cancle(), 取消员工的 Contextcancle()time.Sleep(time.Second * 5)
}func work(ctx context.Context, name string) {for {select {// 看看员工的 Context 还在不在case <-ctx.Done():fmt.Println(time.Now().Format("2006-01-02 15:04:05"), name, "下班!")returndefault:fmt.Println(time.Now().Format("2006-01-02 15:04:05"), name, "加班!。")time.Sleep(time.Second * 1)}}
}
执行结果如下

可以看到, 领导加班7秒, 员工并没有等着领导下班, 在第五秒的时候自己下班了.
相关文章:
Go的 context 包的使用
文章目录背景简介主要方法获得顶级上下文当前协程上下文的操作创建下级协程的Context场景示例背景 在父子协程协作过程中, 父协程需要给子协程传递信息, 子协程依据父协程传递的信息来决定自己的操作. 这种需求下可以使用 context 包 简介 Context通常被称为上下文ÿ…...
微服务为什么要用到 API 网关?
本文介绍了 API 网关日志的价值,并以知名网关 Apache APISIX 为例,展示如何集成 API 网关日志。 作者程小兰,API7.ai 技术工程师,Apache APISIX Contributor。 原文链接 什么是微服务 微服务架构(通常简称为微服务&a…...
SWUST OJ 1042: 中缀表达式转换为后缀表达式【表达式转逆波兰表达式】
题目描述 中缀表达式是一个通用的算术或逻辑公式表示方法,操作符是以中缀形式处于操作数的中间(例:3 4),中缀表达式是人们常用的算术表示方法。后缀表达式不包含括号,运算符放在两个运算对象的后面&#…...
Matlab基础知识
MATLAB批量读入文件和导出文件一、 批量读入文件1.若文件名称有序,则按照文件名称规律循环读取文件(1)读入不同的excelfor i1:1:10strstrcat(F:\数据\v,int2str(i),.xlsx); %连接字符串形成文件名Axlsread(str); end注:变量i为整数时,可以用i…...
动手学深度学习【2】——softmax回归
动手学深度学习网址:动手学深度学习 注:本部分只对基础知识进行简单的介绍并附上完整的代码实现,更多内容可参考上述网址。 前言 前面一节我们谈到了线性回归,它解决的是预测某个值的问题。但是在日常生活这,除了预测…...
深入理解Activity的生命周期
之前学习安卓的时候只是知道生命周期是什么,有哪几个,但具体的详细的东西却不知道,后来看过《Android开发艺术探索》和大量博客之后,才觉得自己真正有点理解生命周期,本文是我对生命周期的认识的总结。废话少说先上图。…...
Go语言刷题常用数据结构和算法
数据结构 字符串 string 访问字符串中的值 通过下标访问 s1 : "hello world"first : s[0]通过切片访问 s2 : []byte(s1) first : s2[0]通过for-range循环访问 for i, v : range s1 {fmt.Println(i, v) }查询字符是否属于特定字符集 // 判断字符串中是否包含a、b、…...
深入vue2.x源码系列:手写代码来模拟Vue2.x的响应式数据实现
前言 Vue响应式原理由以下三个部分组成: 数据劫持:Vue通过Object.defineProperty()方法对data中的每个属性进行拦截,当属性值发生变化时,会触发setter方法,通知依赖更新。发布-订阅模式:Vue使用发布-订阅…...
Linux线程控制
本篇我将学习如何使用多线程。要使用多线程,因为Linux没有给一般用户直接提供操作线程的接口,我们使用的接口,都是系统工程师封装打包成原生线程库中的。那么就需要用到原生线程库。因此,需要引入-lpthread,即连接原生…...
【LeetCode】剑指 Offer(20)
目录 题目:剑指 Offer 38. 字符串的排列 - 力扣(Leetcode) 题目的接口: 解题思路: 代码: 过啦!!! 写在最后: 题目:剑指 Offer 38. 字符串的…...
FutureTask中的outcome字段是如何保证可见性的?
最近在阅读FutureTask的源码是发现了一个问题那就是源码中封装结果的字段并没有使用volatile修饰,源码如下:public class FutureTask<V> implements RunnableFuture<V> {/*** 状态变化路径* Possible state transitions:* NEW -> COMPLET…...
直播回顾 | 聚焦科技自立自强,Bonree ONE 助力国产办公自动化平稳替代
3月5日,两会发布《政府工作报告》,强调科技政策要聚焦自立自强。 统计显示,2022年金融信创项目数同比增长300%,金融领域信创建设当前已进入发展爆发期,由国有大型银行逐渐向中小型银行、非银金融机构不断扩展。信创云…...
深入理解Linux进程
进程参数和环境变量的意义一般情况下,子进程的创建是为了解决某个问题。那么解决问题什么问题呢?这个就需要进程参数和环境变量来进行决定的。子进程解决问题需要父进程的“数据输入”(进程参数 & 环境变量)设计原则:3.1 子进程启动的时候…...
Vue3之组件间的双向绑定
何为组件间双向绑定 我们都知道当父组件改变了某个值后,如果这个值传给了子组件,那么子组件也会自动跟着改变,但是这是单向的,使用v-bind的方式,即子组件可以使用父组件的值,但是不能改变这个值。组件间的…...
Java语法基础(一)
目录 代码注释方法 编码规范 基本数据类型及取值范围 变量和常量的声明与赋值 变量 常量 标识符 基本数据类型的使用 整数类型的使用 浮点类型的使用 布尔类型的使用 字符类型的使用 代码注释方法 单行注释:使用“//”进行单行注释多行注释:使…...
优思学院|零质量控制是什么概念?
零质量控制(Zero Quality Control)是指一个理想的系统,可以生产没有任何缺陷的产品,因此不需要频繁的检查,从而节省时间和金钱。那些追求过程优化并致力于持续过程改进的组织将零质量控制(Zero Quality Con…...
2023-03-09 CMU15445-Query Execution
摘要: CMU15445, Project #3 - Query Execution 参考: Project #3 - Query Execution | CMU 15-445/645 :: Intro to Database Systems (Fall 2022) https://github.com/cmu-db/bustub 要求: OVERVIEW At this point in the semester, you have implemented the internal co…...
vuedraggable的使用
Draggable为基于Sortable.js的vue组件,用以实现拖拽功能。 特性 支持触摸设备 支持拖拽和选择文本 支持智能滚动 支持不同列表之间的拖拽 不以jQuery为基础 和视图模型同步刷新 和vue2的国度动画兼容 支持撤销操作 当需要完全控制时,可以抛出所有变化 可…...
双馈风力发电机-900V直流混合储能并网系统MATLAB仿真
MATLAB2016b主体模型:双馈感应风机模块、采用真实风速数据。混合储能模块、逆变器模块、转子过电流保护模块、整流器控制模块、逆变器控制模块。直流母线电压:有功、无功输出(此处忘记乘负一信号输出),所以是负的。蓄电…...
leader选举过程
启动electionTimer,进行leader选举。 一段时间没有leader和follower通信,就会超时,开始选举leader过程。有个超时时间,如果到了这个时间,就会触发一个回调函数。具体如下: private void handleElectionTimeout() {boo…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
