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

golang:context

context作用

goroutine的退出机制

多个goroutine都是平行的被调度的,多个goroutine如何协调工作涉及通信、同步、通知和退出

  • 通信:goroutine之间的通信同步chan通道

  • 同步:不带缓冲的chan提供了一个天然的同步等待机制。通过WaitGroup也可以为多个goroutine提供同步等待机制

  • 通知:这个通知和上面通信的数据不一样,通知通常不是业务数据,而是管理、控制流数据。要处理这个也好办,在输入端绑定两个chan,一个用于业务流数据,另一个用于异常通知数据,然后通过 select 收敛进行处理。这个方案可以解决简的问题,但不是一个通用的解决方案。

  • 退出:goroutine 之间没有父子关系,如何通知 goroutine 退出?可以通过增加一个个单独的通道,借助通道和 select 的广播机制( close channel to broadcast)实现退出

通知退出机制:

  • 读取已经关闭的通道不会引起阻塞,也不会导致panic,而是立即返回该通道存储类型的零值

  • 关闭select监听的某个通道能使select立即感知这种通知,然后进行相应的处理,即所谓的退出通知机制

contet库的设计目的就是跟踪 goroutine调用树,并在这些goroutine 调用树中递通知和元数据

  • 退出通知机制:通知可以传递给整个 goroutine调用树上的每一个goroutine

  • 传递数据:数据可传递给整个goroutine 调用树上的每一个goroutine

使用

var wg sync.WaitGroup
func main() {background := context.Background()//通过cancel进行控制/*cancelctx, cancelFunc := context.WithCancel(background)wg.Add(2)go jiankong1(cancelctx)time.Sleep(time.Second * 2)println("并不是因为主协程退出,而导致另一个协程退出,而是通过cancel方法通知另一个协程进行退出!")cancelFunc()wg.Wait()println("完成退出")*///通过deadline进行控制,也可以通过返回的cancelFunc手动进行控制/*deadline, _ := context.WithDeadline(background, time.Now().Add(time.Second*2))go deadF(deadline)time.Sleep(time.Second * 4)println("结束")*///通过timeout控制,也可以通过返回的cancelFunc手动进行控制   超时以后报的错和deadline控制方式一样 context deadline exceededtimeout, _ := context.WithTimeout(background, time.Second*2)go deadF(timeout)time.Sleep(time.Second * 4)println("结束")
}func deadF(ctx context.Context) {for true {select {case <-ctx.Done():fmt.Println("只给了两秒的执行时间,时间到了,我得退出了。")//此处打印的错误为 context deadline exceededprintln(ctx.Err().Error())returndefault:time.Sleep(time.Millisecond * 1000)fmt.Println("我正在执行...")}}
}func jiankong1(ctx context.Context) {defer wg.Done()cancel, _ := context.WithCancel(ctx)go jiankong2(cancel)for true {select {case <-ctx.Done():fmt.Println("别人通知我主动退出了。在此处进行收尾工作,释放资源等")//此处报错为:context canceledfmt.Println(ctx.Err().Error())returndefault:time.Sleep(time.Millisecond * 100)fmt.Println("我在持续监控中...")}}
}func jiankong2(ctx context.Context) {defer wg.Done()for true {select {case <-ctx.Done():fmt.Println("上级通知我主动退出了。")fmt.Println(ctx.Err().Error())returndefault:time.Sleep(time.Millisecond * 100)fmt.Println("me在持续监控中...")}}
}

Tips:

异步任务使用context注意点:

使用go func进行异步任务传入context时,要考虑context的过期时间,如果异步任务不考虑过期时间,则最好传入一个无过期时间的context,负责异步任务多或执行时间长context会过期,影响异步任务的执行。

场景:mongo批量插入数据后,将返回的Id集合传入异步任务(在异步任务中通过id查询数据),如果共用了接口设置过期时间的context,可能会导致一部分数据查询不到(context过期导致)

相关文章:

golang:context

context作用 goroutine的退出机制 多个goroutine都是平行的被调度的&#xff0c;多个goroutine如何协调工作涉及通信、同步、通知和退出 通信&#xff1a;goroutine之间的通信同步chan通道 同步&#xff1a;不带缓冲的chan提供了一个天然的同步等待机制。通过WaitGroup也可以…...

探讨代理IP与Socks5代理在跨界电商中的网络安全应用

在数字化时代&#xff0c;跨界电商已经成为了商业世界中的一大趋势。然而&#xff0c;跨越国界的电商活动也伴随着网络安全挑战。本文将讨论如何利用代理IP和Socks5代理技术来提高跨界电商中的网络安全&#xff0c;同时也探讨了与游戏相关的爬虫应用。 1. 代理IP和Socks5代理的…...

Guava Cache介绍-面试用

一、Guava Cache简介 1、简介 Guava Cache是本地缓存&#xff0c;数据读写都在一个进程内&#xff0c;相对于分布式缓存redis&#xff0c;不需要网络传输的过程&#xff0c;访问速度很快&#xff0c;同时也受到 JVM 内存的制约&#xff0c;无法在数据量较多的场景下使用。 基…...

ARM 汇编指令作业(求公约数、for循环实现1-100之间和、从SVC模式切换到user模式简单写法)

1、求两个数最大公约数 .text .globl _start_start:mov r0, #9mov r1, #15 Loop: 循环cmp r0,r1 比较r0和r1的大小beq stop 当r0和r1相等时&#xff0c;跳到stop标签subhi r0,r0,r1 r0-r1>0 时&#xff0c;证明r0>r1,将r0-r1的值赋给r0&…...

Go - 【字符串,数组,哈希表】常用操作

一. 字符串 字符串长度&#xff1a; s : "hello" l : len(s) fmt.Println(l) // 输出 5遍历字符串&#xff1a; s : "hello" for i, c : range s {fmt.Printf("%d:%c ", i, c) } // 输出&#xff1a;0:h 1:e 2:l 3:l 4:ofor i : 0; i < le…...

vue 普通组件的 局部注册

vue 普通组件的 注册 11 Vue2_3入门到实战-配套资料\01-随堂代码素材\day03\素材\00-准备代码\小兔鲜首页静态页\src...

医疗虚拟仿真和虚拟现实有什么区别?哪个更好?

随着我们在仿真教育中越来越多地使用新技术&#xff0c;区分虚拟模式的类型很重要。虚拟仿真是一个统称&#xff0c;用来概括术语来描述各种基于仿真的体验&#xff0c;从基于屏幕的平台到沉浸式虚拟现实。然而&#xff0c;各虚拟平台在保真度、沉浸感和临场感的水平上有很大差…...

【.net core】yisha框架使用nginx代理swagger接口无法访问问题

后端代码配置 #在StartUp.cs文件中Configure方法中增加以下代码 app.UseSwagger(c >{//代理路径访问c.PreSerializeFilters.Add((doc, item) >{//根据代理服务器提供的协议、地址和路由&#xff0c;生成api文档服务地址doc.Servers new List<OpenApiServer>{ new…...

uniapp录音功能和音频播放功能制作

录音功能 在 UniApp 中&#xff0c;你可以使用 uni.getRecorderManager() 方法来创建一个录音管理器实例&#xff0c;从而实现录音功能。 以下是一个示例&#xff0c;演示了如何在 UniApp 中使用 uni.getRecorderManager() 实现录音功能&#xff1a; // 在需要录音的页面或组…...

服务器数据恢复-LINUX操作系统下各文件系统误删除/格式化数据的恢复方案

服务器数据恢复环境&#xff1a; 基于EXT2/EXT3/EXT4/Reiserfs/Xfs文件系统的Linux操作系统。 服务器故障&#xff1a; LINUX操作系统下误删除/格式化数据。 服务器数据恢复过程&#xff1a; 1、首先会检测服务器是否存在硬件故障&#xff0c;如果检测出硬件故障&#xff0c;交…...

python/C++二分查找库函数(lower_bound() 、upper_bound,bisect_left,bisect_right)

二分查找是一种经典的搜索算法&#xff0c;广泛应用于有序数据集中。它允许在大型数据集中高效地查找目标元素&#xff0c;减少了搜索的时间复杂度。本文将介绍在 C 和 Python 中内置的二分查找函数&#xff0c;让二分查找变得更加容易。 c lower_bound() 、upper_bound 定义…...

爬虫 — App 爬虫(二)

目录 一、Appium介绍二、node.js 安装三、Java 的 SDK 安装以及配置1、安装步骤2、配置环境变量 四、安卓环境的配置1、配置环境变量 五、Appium 安装1、安装2、打开 APP3、使用 六、Appium 使用1、定位数据&#xff08;方法一&#xff0c;不常用&#xff09;2、定位数据&#…...

汽车电子相关术语

SOA SOA&#xff08;Service-Oriented Architecture&#xff0c;面向服务的架构&#xff09;是一种在计算机环境中设计、开发、部署和管理离散模型的方法。是由Garnter1996年提出的概念&#xff0c;将应用程序的不同功能单元&#xff08;称为服务&#xff09;进行拆分&#xf…...

Python 找出最大数

"""在输入的三个数中找出最大知识点&#xff1a;1、条件嵌套语句if/else2.字符串分割函数split()3、列表元素索引4、数据类型转换举一反三&#xff1a;1、如何控制只能输入三个数&#xff0c;否则重新输入2、如何避免输入无效字母"""# 定义一个变…...

Spring Security 用了那么久,你对它有整体把控吗?

文章目录 1.Servlet Filter&#xff1a;守门人的角色2.DelegatingFilterProxy&#xff1a;桥接 Servlet 和 Spring 的神器3.FilterChainProxy&#xff1a;Spring Security 过滤器链的管家3.SecurityFilterChain&#xff1a;Security 过滤器的串绳4.Spring Security 中的过滤器机…...

vue+minio实现文件上传操作

vueminio实现文件上传操作 minio文件上传vueminio实现文件上传操作 minio文件上传 minio文件上传有两种方法&#xff1a; 第一种是通过ak&#xff0c;sk&#xff0c;调用minio的sdk putObject进行文件上传&#xff1b;该方法支持go&#xff0c;java&#xff0c;js等各种语言&…...

使用JavaScript实现无限滚动的方法

前言 在网页设计中&#xff0c;无限滚动是一种常见的交互方式&#xff0c;用户可持续地加载更多内容而无需刷新页面&#xff0c;提高用户体验。本文将介绍如何运用JavaScript实现无限滚动的效果&#xff0c;使网页能够自动加载更多数据&#xff0c;减轻用户加载新页的负担&…...

html学习综合案例1

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>个人简介</title> </head> <body>…...

神经节苷脂抗体——博迈伦

神经节苷脂抗体是指人体免疫系统中产生的一类抗体&#xff0c;其主要作用是攻击神经节苷脂抗原物质。神经节苷脂是一种存在于神经细胞表面的重要分子&#xff0c;参与了神经细胞间的信号传导和细胞黏附等重要功能。正常情况下&#xff0c;人体免疫系统不会对神经节苷脂产生抗体…...

【Unity】简单的深度虚化shader

【Unity】简单的深度虚化shader 实现效果 可以用于对地图场景边界的白模处理 实现方法 1.关键方法 UnityObjectToClipPos&#xff1a;将物体坐标转换为屏幕坐标 LinearEyeDepth&#xff1a;将屏幕坐标中的z值转换为实际的深度值 saturate&#xff1a;将值规范到0~1之间&a…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...