当前位置: 首页 > news >正文

golang context

作用:用于在go协程中 传递上下文、超时、取消、传值

底层实现:是由互斥锁、channel、map来实现的
互斥锁:保护临界资源
channel: 用于信号通知,比如ctx.Done()
map: 保存父ctx下派生的所有子ctx, 父ctx关闭,子ctx都关闭

实现的接口

type Context interface {Deadline() (deadline time.Time, ok bool)Done() <-chan struct{}Err() errorValue(key interface{}) interface{}
}

空ctx

type emptyCtx intfunc (*emptyCtx) Deadline() (deadline time.Time, ok bool) {return
}func (*emptyCtx) Done() <-chan struct{} {return nil
}func (*emptyCtx) Err() error {return nil
}func (*emptyCtx) Value(key interface{}) interface{} {return nil
}

cancel ctx

使用map保存所有子ctx,确保父ctx cancel后,子ctx也cancel

type cancelCtx struct {Contextmu       sync.Mutex            // protects following fieldsdone     chan struct{}         // created lazily, closed by first cancel callchildren map[canceler]struct{} // set to nil by the first cancel callerr      error                 // set to non-nil by the first cancel call
}func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {if parent == nil {panic("cannot create context from nil parent")}c := newCancelCtx(parent)propagateCancel(parent, &c)return &c, func() { c.cancel(true, Canceled) }
}// newCancelCtx returns an initialized cancelCtx.
func newCancelCtx(parent Context) cancelCtx {return cancelCtx{Context: parent}
}func propagateCancel(parent Context, child canceler) {fmt.Println("propagateCancel")done := parent.Done()if done == nil {return // parent is never canceled}select {case <-done:// parent is already canceledchild.cancel(false, parent.Err())returndefault:}if p, ok := parentCancelCtx(parent); ok {p.mu.Lock()if p.err != nil {// parent has already been canceledchild.cancel(false, p.err)} else {if p.children == nil {p.children = make(map[canceler]struct{})}// 保存子ctxp.children[child] = struct{}{}}p.mu.Unlock()} else {atomic.AddInt32(&goroutines, +1)go func() {select {case <-parent.Done():child.cancel(false, parent.Err())case <-child.Done():}}()}
}func (c *cancelCtx) cancel(removeFromParent bool, err error) {if err == nil {panic("context: internal error: missing cancel error")}c.mu.Lock()if c.err != nil {c.mu.Unlock()return // already canceled}c.err = errif c.done == nil {c.done = closedchan} else {close(c.done) // 关闭channel, 用于通知ctx.Done()}// 关闭所有子ctxfor child := range c.children {// NOTE: acquiring the child's lock while holding parent's lock.child.cancel(false, err)}c.children = nilc.mu.Unlock()if removeFromParent {removeChild(c.Context, c)}
}

timeout ctx

在cancelctx的基础上实现,只是多了个定时器自动调用cancel

type timerCtx struct {cancelCtxtimer *time.Timer // Under cancelCtx.mu.deadline time.Time
}func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) {if parent == nil {panic("cannot create context from nil parent")}if cur, ok := parent.Deadline(); ok && cur.Before(d) {// The current deadline is already sooner than the new one.return WithCancel(parent)}c := &timerCtx{cancelCtx: newCancelCtx(parent),deadline:  d,}propagateCancel(parent, c)dur := time.Until(d)if dur <= 0 {c.cancel(true, DeadlineExceeded) // deadline has already passedreturn c, func() { c.cancel(false, Canceled) }}c.mu.Lock()defer c.mu.Unlock()if c.err == nil {c.timer = time.AfterFunc(dur, func() {c.cancel(true, DeadlineExceeded)})}return c, func() { c.cancel(true, Canceled) }
}

value ctx

type valueCtx struct {Contextkey, val interface{}
}
func WithValue(parent Context, key, val interface{}) Context {if parent == nil {panic("cannot create context from nil parent")}if key == nil {panic("nil key")}//	if !reflectlite.TypeOf(key).Comparable() {//	panic("key is not comparable")//}return &valueCtx{parent, key, val}
}
func (c *valueCtx) Value(key interface{}) interface{} {if c.key == key {return c.val}return c.Context.Value(key)
}

相关文章:

golang context

作用&#xff1a;用于在go协程中 传递上下文、超时、取消、传值 底层实现&#xff1a;是由互斥锁、channel、map来实现的 互斥锁&#xff1a;保护临界资源 channel: 用于信号通知&#xff0c;比如ctx.Done() map: 保存父ctx下派生的所有子ctx, 父ctx关闭&#xff0c;子ctx都关…...

GPT中的Transformer架构以及Transformer 中的注意力机制

目录 1 GPT中的Transformer架构 2 transformer中的注意力机制 参考文献&#xff1a; 看了两个比较好的视频&#xff0c;简单做了下笔记。 1 GPT中的Transformer架构 GPT是Generative Pre-trained Transformer单词的缩写&#xff0c;其中transformer是一种特定的神经网络&a…...

Hive的简单学习二

一Hive 库的基本操作 1.1 建库 1.默认路径是/user/hive/warehouse 例如 我输入命令 create database text1 则text1出现在 warehouse目录下 2.指定位置创建数据库 create database text2 location /bigdata29/bigdata29db 后面的路径是hdfs的路径 3.最终写法 加上if n…...

Qt事件处理机制3-事件函数的分发

Qt开发中&#xff0c;经常重写event函数和具体的事件处理函数&#xff0c;例如mousePressEvent、paintEvent等&#xff0c;那么这些具体的事件处理函数是怎样被调用的呢&#xff1f;答案是由继承自QObject的类中的event函数来处理事件分发。这里以间接继承自QWidget的派生类MyB…...

4月9号总结

java学习 一.steam流 1.介绍 Stream 是 Java 8 中引入的一种处理集合数据的新抽象。它提供了一种高效且便利的方式来处理集合中的元素&#xff0c;支持函数式编程的特性&#xff0c;使得集合操作变得更加简洁和灵活。 2.创建 List和Set可以直接调用接口的steam方法转换为流 …...

Linux生态系统:探索Linux的开源世界

Linux生态系统:探索Linux的开源世界 在前面的博客中,我们深入探讨了Linux的各种技能和技巧,从入门到进阶,再到高手级别。这一路走来,相信大家对Linux已经有了全面的认识和掌握。然而,Linux的魅力远不止于此。今天,我们将进一步探索Linux生态系统,了解Linux在开源世界中的重要地…...

XILINX 10G PCS PMA IP核使用

文章目录 一、设计框图二、模块设计三、IP核配置四、上板验证五、总结 一、设计框图 关于GT高速接口的设计一贯作风&#xff0c;万兆以太网同样如此&#xff0c;只不过这里将复位逻辑和时钟逻辑放到了同一个文件ten_gig_eth_pcs_pma_0_shared_clock_and_reset当中。如果是从第…...

Scrapy框架内存泄漏问题及解决

说明&#xff1a;仅供学习使用&#xff0c;请勿用于非法用途&#xff0c;若有侵权&#xff0c;请联系博主删除 作者&#xff1a;zhu6201976 一、问题背景及原因 官方文档&#xff1a;Debugging memory leaks — Scrapy 2.11.1 documentation Scrapy是一款功能强大的网络爬虫框…...

app 创建快捷入口 在手机上面多个icon

activity-alias详解及应用-CSDN博客 Android动态修改应用图标最佳实践 - 简书 AndroidManifest.xml 中 <activity-aliasandroid:name"包名.ui.mine.SecondActivityAlias"android:label"快捷入口"android:icon"mipmap/collection_one"andro…...

【网安小白成长之路】6.pkachu、sql-lbas、upload-lbas靶场搭建

&#x1f42e;博主syst1m 带你 acquire knowledge&#xff01; ✨博客首页——syst1m的博客&#x1f498; &#x1f51e; 《网安小白成长之路(我要变成大佬&#x1f60e;&#xff01;&#xff01;)》真实小白学习历程&#xff0c;手把手带你一起从入门到入狱&#x1f6ad; &…...

vue 项目中添加DES加密

vue 项目中添加DES加密 由于现在项目使用http协议&#xff0c;且登录界面是明文传输&#xff0c;项目真正上线后基本的密码传输都很不安全。 决定用前端框架加密后再进行传输&#xff0c;以提高密码传输过程中的安全性。 crypto-js 是一个流行的 JavaScript 加密库&#xff0…...

【记录问题】如何测试虚拟机已经可以连接网络

如何测试虚拟机已经可以连接网络 要测试虚拟机是否已经连接网络&#xff0c;可以采取以下步骤&#xff1a; 检查虚拟网络编辑器 使用管理员权限打开虚拟网络编辑器&#xff0c;检查NAT方式下的虚拟子网网段。 确保虚拟机的网络设置与虚拟子网网段相匹配。检查虚拟机网络设置 …...

MySQL数据库的详解(1)

DDL&#xff08;数据库操作&#xff09; 查询 查询所有数据库&#xff1a;show databases;当前数据库&#xff1a;select database(); 创建 创建数据库&#xff1a;create database [ if not exists] 数据库名 ; 使用 使用数据库&#xff1a;use 数据库名 ; 删除 删除数…...

Python 网络爬虫技巧分享:优化 Selenium 滚动加载网易新闻策略

简介 网络爬虫在数据采集和信息获取方面发挥着重要作用&#xff0c;而滚动加载则是许多网站常用的页面加载方式之一。针对网易新闻这样采用滚动加载的网站&#xff0c;如何优化爬虫策略以提高效率和准确性是一个关键问题。本文将分享如何利用 Python 中的 Selenium 库优化滚动…...

Apache SeaTunnel 社区 3 月月报

各位热爱 SeaTunnel 的小伙伴们&#xff0c;SeaTunnel 社区 3 月月报来啦&#xff01;这里将记录 SeaTunnel 社区每个月的重要更新&#xff0c;并评选出月度之星&#xff0c;欢迎关注。 SeaTunnel 月度 Merge Stars 感谢以下小伙伴 3 月为 Apache SeaTunnel 做的精彩贡献&…...

ElasticSearch 的 ConstantScoreQuery 的理解

ConstantScoreQuery的定义&#xff1a; A query that wraps another query and simply returns a constant score equal to 1 for every document that matches the query. It therefore simply strips of all scores and always returns 1. 结合DisMaxQueryBuilder可以查找所…...

【RV1106的ISP使用记录之一】基础环境搭建

公司缺少ISP工程师&#xff0c;做为图像算法工程师的我这就不就给顶上来了么&#xff0c;也没给发两份工资&#xff0c;唉~ 先写个标题&#xff0c;占一个新坑&#xff0c;记录RK平台的传统ISP工作。 一、基础环境的硬件包括三部分&#xff1a; 1、相机环境&#xff0c;用于采…...

mars3d.MaterialType.Image2修改配置面状:图片2的speed数值实现动画效果说明

摘要&#xff1a; mars3d.MaterialType.Image2修改配置面状&#xff1a;图片2的speed数值实现动画效果说明 前提&#xff1a; 1.在示例中&#xff0c;尝试给mars3d.MaterialType.Image2材质的图片加上speed参数&#xff0c;实现动画效果&#xff0c;但是没有看到流动效果说明…...

Elasticsearch部署安装

环境准备 Anolis OS 8 Firewall关闭状态&#xff0c;端口自行处理 Elasticsearch&#xff1a;7.16.1&#xff08;该版本需要jdk11&#xff09; JDK&#xff1a;11.0.19 JDK # 解压 tar -zxvf jdk-11.0.19_linux-x64_bin.tar.gz# 编辑/etc/profile vim /etc/profile# 加入如下…...

Android零基础入门(一)配置环境和安装Android Studio

闲来无事学一下Android&#xff0c;本人目前java为主&#xff0c;jdk的环境就不赘述了 配置环境 Java JDK5 或 以后版本 Android SDK Java运行时环境&#xff08;JRE&#xff09; Android Studio 你可以从 Oracle 的 Java 网站&#xff1a;JDKJava SE下载下载最新版本的 Jav…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...