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

golang中context使用总结

一、context使用注意事项

在使用context时,有一些需要注意的事项,以及一些与性能优化相关的建议:

  1. 避免滥用context传递数据:context的主要目的是传递请求范围的数据和取消信号,而不是用于传递全局状态或大量数据。滥用context传递大量数据可能导致上下文对象变得臃肿,增加内存和GC压力。

  2. 不要修改已传递的context:传递的context是不可变的,即使在函数内部对其调用cancel方法也不会影响调用方的context。如果需要对context进行修改,应该通过返回一个新的派生context来实现。

  3. 只在需要时传递context:不要将context作为函数参数无限制地传递,而是在需要时传递。这样可以避免不必要的复杂性和代码膨胀。

  4. 及早检查取消信号:在使用context的地方,应该及早检查ctx.Done()的返回值,以尽早响应取消信号。在耗时操作前或可能阻塞的地方,应该通过select语句来监听多个操作,包括取消信号、超时和其他channel。

  5. 使用WithCancel替代WithTimeout:在可能的情况下,优先使用WithCancel函数来设置取消信号,而不是仅仅依赖于WithTimeout函数。这样可以有更精确的控制和更灵活的处理方式。

  6. 优化context的传递:在频繁调用的函数链中,避免在每个函数中重复传递相同的context,可以通过使用结构体或函数闭包将context作为参数进行传递,从而减少代码重复和提升性能。

  7. 及时取消不再需要的goroutine:如果在多个goroutine中使用context,确保在不再需要时及时取消goroutine,以避免资源浪费和潜在的goroutine泄漏。

这些注意事项和性能优化建议可帮助确保正确且高效地使用context,避免滥用和性能问题。根据具体场景和需求,可以灵活使用context的机制来优化代码的可读性、并发安全性和性能。

二、context使用举例

在这里插入图片描述

在Go语言中,context(上下文)是在不同goroutine之间传递请求范围数据、取消信号和超时处理的一种机制。下面详细介绍context的每种使用情况和相应的代码举例:

  1. 传递请求范围数据:

    package mainimport ("context""fmt"
    )// 定义一个键类型(key)用于context中的数据传递
    type key string// 在context中设置数据
    func withValue(ctx context.Context) {// 使用WithValue将数据存储在context中ctxWithData := context.WithValue(ctx, key("name"), "John")// 调用另一个函数,并将带有数据的context传递给它printName(ctxWithData)
    }// 从context中获取并使用数据
    func printName(ctx context.Context) {// 从context中获取数据,并进行类型断言if name, ok := ctx.Value(key("name")).(string); ok {fmt.Println("Name:", name)}
    }func main() {// 创建根contextctx := context.Background()// 传递context并设置数据withValue(ctx)
    }
    

    在上面的示例中,我们定义了一个key类型,用于在context中存储数据。然后,我们使用WithValue函数将数据存储在带有数据的context ctxWithData 中,并将其传递给printName函数。在printName函数中,我们使用Value方法从context中获取数据,并进行类型断言后打印出来。

  2. 取消信号:

    package mainimport ("context""fmt""time"
    )// 模拟一些耗时操作
    func performTask(ctx context.Context) {// 检查是否接收到取消信号select {case <-ctx.Done():fmt.Println("Task canceled")returndefault:// 模拟长时间运行的任务time.Sleep(5 * time.Second)fmt.Println("Task completed")}
    }func main() {// 创建根contextctx := context.Background()// 派生子context,并设置取消信号ctx, cancel := context.WithCancel(ctx)// 启动耗时操作的goroutine,并传递带有取消信号的contextgo performTask(ctx)// 模拟一些操作后取消任务time.Sleep(2 * time.Second)cancel() // 发送取消信号// 等待一段时间,确保程序有足够的时间处理取消信号time.Sleep(1 * time.Second)
    }
    

    在上面的示例中,我们创建了一个任务函数performTask,该函数会检查是否接收到取消信号。使用context.WithCancel函数创建派生的子context,并通过调用返回的cancel函数发送取消信号。然后,我们在一个goroutine中运行任务函数,并通过传递带有取消信号的context来监听取消信号。在主goroutine中,我们等待一段时间后调用cancel函数发送取消信号。当任务函数接收到取消信号后,它会打印"Task canceled"。

  3. 超时处理:

    package mainimport ("context""fmt""time"
    )// 模拟一些耗时操作
    func performTask(ctx context.Context) {// 检查是否接收到取消信号或超时select {case <-ctx.Done():fmt.Println("Task canceled")case <-time.After(5 * time.Second):fmt.Println("Task completed")}
    }func main() {// 创建根contextctx := context.Background()// 派生子context,并设置超时时间ctx, cancel := context.WithTimeout(ctx, 3*time.Second)defer cancel()// 启动耗时操作的goroutine,并传递带有超时设置的contextgo performTask(ctx)// 等待一段时间,确保程序有足够的时间处理超时或取消信号time.Sleep(5 * time.Second)
    }
    

    在上面的示例中,我们创建了一个任务函数performTask,该函数会检查是否接收到取消信号或超时。使用context.WithTimeout函数创建派生的子context,并通过调用返回的cancel函数来设置超时时间。然后,我们在一个goroutine中运行任务函数,并传递带有超时设置的context来监听超时或取消信号。在主goroutine中,我们等待一段时间以确保程序有足够的时间处理超时或取消信号。当超过超时时间后,任务函数会打印"Task canceled"。

这些是context在Go语言中的常见用法,它们使得在并发环境中处理请求范围数据、取消信号和超时变得更加简单和可靠。根据具体的使用场景,你可以选择适当的context函数来创建和传递context,并根据需要进行取消和超时处理。

相关文章:

golang中context使用总结

一、context使用注意事项 在使用context时&#xff0c;有一些需要注意的事项&#xff0c;以及一些与性能优化相关的建议&#xff1a; 避免滥用context传递数据&#xff1a;context的主要目的是传递请求范围的数据和取消信号&#xff0c;而不是用于传递全局状态或大量数据。滥用…...

医院数字化LIS(检验信息系统)源码

临床检验信息管理系统&#xff08;LIS&#xff09;是利用计算机连接医疗设备&#xff0c;通过计算机信息处理技术&#xff0c;将医院检验科或实验室的临床检验数据进行自动收集、存储、处理、提取、传输和交换&#xff0c;满足所有授权用户的功能需求。 一、系统概述 1.LIS&am…...

挑战单芯片NOA,这款“All in one”方案或将改变主流市场走向

随着降本增效、电子架构升级&#xff08;尤其是跨域计算、多域融合等概念&#xff09;以及供应链减复&#xff08;降低电子物料的SKU&#xff09;的需求愈加明确&#xff0c;对于车载计算赛道&#xff0c;也带来新的变化。 比如&#xff0c;去年9月&#xff0c;英伟达率先发布下…...

CODING DevOps产品认证笔记

1.敏捷&精益&瀑布概述 1.1 敏捷软件开发 第一章敏捷软件开发背景 背景&#xff1a;乌卡时代 易变性:当今世界的变化越来越多越来越快&#xff0c;越来越不可预测。不确定性:历史上的任何一个时代所带来的经验已经无法为当今世界的所有变化提供参照。复杂性:事物间的…...

信息系统项目管理师 第四版 第5章 信息系统工程

1.软件工程 1.1.架构设计 1.2.需求分析 1.3.软件设计 1.4.软件实现 1.5.部署交互 1.6.过程管理 2.数据工程 2.1.数据建模 2.2.数据标准化 2.3.数据运维 2.4.数据开发利用 2.5.数据库安全 3.系统集成 3.1.集成基础 3.2.网络集成 3.3.数据集成 3.4.软件集成 3.…...

对话芯动科技 | 助力云游戏 4K级服务器显卡的探索与创新

2021年芯动科技推出了基于IMG BXT GPU IP的风华1号显卡。单块风华1号显卡可在台式机和云游戏中实现4K级别的性能&#xff0c;渲染能力达到5 TFLOPS&#xff0c;如果在服务器中同时运行两块显卡&#xff0c;性能还可翻倍。该显卡是为不断扩大的安卓云游戏市场量身定制的&#xf…...

[HTML]Web前端开发技术1,meta,HBuilder等——喵喵画网页

希望你开心&#xff0c;希望你健康&#xff0c;希望你幸福&#xff0c;希望你点赞&#xff01; 最后的最后&#xff0c;关注喵&#xff0c;关注喵&#xff0c;关注喵&#xff0c;大大会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的…...

网上申请的电信卡能用多长时间?可以长期使用吗?

我们在网上总能看到一些关于流量卡的广告&#xff0c;都是19元&#xff0c;29元100多g的套餐&#xff0c;乍一看这些套餐非常便宜&#xff0c;但是小编提醒大家一定要注意优惠期。 ​  网上的流量卡套餐&#xff0c;都是由基础套餐额外赠送充值送话费等内容组成&#xff0c;…...

交换机的工作原理

局域网交换技术是数据链路层上的技术&#xff0c;就是转发数据帧。在数据通信中&#xff0c;所有交换设备都执行两个基本操作&#xff1a; 交换数据帧生成并维护交换地址表 交换数据帧 交换机根据数据帧的MAC地址&#xff08;物理地址&#xff09;进行数据帧的转发操作。交换…...

如何使用ArcGIS Pro制作粉饰效果

在地图上&#xff0c;如果某个部分比较重要&#xff0c;直接的制图不能将其凸显出来&#xff0c;如果想要突出显示重要部分&#xff0c;可以通过粉饰效果来实现&#xff0c;这里为大家介绍一下方法&#xff0c;希望能对你有所帮助。 数据来源 本教程所使用的数据是从水经微图…...

CSS滚动捕获 scroll-snap-align

CSS滚动捕获 scroll-snap-align 看到 align, 就条件反射想到对齐方式, 嗯猜对了. 不过要先看一下若干名词介绍 scroll-snap-align 指定了盒子的 snap position, 即盒子 snap area 和滚动容器的 snapport 的对齐方式. 这个属性是定义在滚动元素上, 而不是滚动容器上 语法 这个…...

基础课8——中文分词

中文分词指的是将一个汉字序列切分成一个一个单独的词。分词就是将连续的字序列按照一定的规范重新组合成词序列的过程。在英文的行文中&#xff0c;单词之间是以空格作为自然分界符的&#xff0c;而中文只是字、句和段能通过明显的分界符来简单划界&#xff0c;唯独词没有一个…...

OpenHarmony应用开发入门教程(一、开篇)

前言 华为正式宣布2024年发布的华为鸿蒙OS Next版将不再兼容安卓系统。这一重大改变&#xff0c;预示着华为鸿蒙OS即将进入一个全新的阶段。 都说科技无国界&#xff0c;这是骗人的鬼话。谷歌的安卓12.0系统早已发布&#xff0c;但是自从受到美影响&#xff0c;谷歌就拒绝再向…...

vue侦听器详解及代码

在 Vue 中&#xff0c;我们可以使用侦听器&#xff08;watcher&#xff09;来监听数据的变化&#xff0c;并在数据发生变化时执行相应的操作。Vue 提供了 watch 选项来定义侦听器&#xff0c;并可以使用 vm.$watch 方法来创建侦听器。 下面是一个简单的示例&#xff0c;我们监…...

Python爬虫的七个常用技巧总结,这些你一定得知道!

文章目录 前言1、基本抓取网页2、使用代理IP3、Cookies处理4、伪装成浏览器5、验证码的处理6、gzip压缩7、多线程并发抓取关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战…...

【Linux】U盘安装的cfg引导文件配置

isolinux.cfg文件 default vesamenu.c32 timeout 600display boot.msg# Clear the screen when exiting the menu, instead of leaving the menu displayed. # For vesamenu, this means the graphical background is still displayed without # the menu itself for as long …...

Theory behind GAN

假如要生成一些人脸图&#xff0c;实际上就是想要找到一个分布&#xff0c;从这个分布内sample出来的图片像是人脸&#xff0c;分布之外生成的就不像人脸。而GAN要做的就是找到这个distribution。 在GAN之前用的是Maximum Likelihood Estimation。 Maximum Likelihood Estimat…...

《Deep learning for fine-grained image analysis: A survey》阅读笔记

论文标题 《Deep learning for fine-grained image analysis: A survey》 作者 魏秀参&#xff0c;旷世研究院 初读 摘要 细粒度图像分析&#xff08;FGIA&#xff09;的任务是分析从属类别的视觉对象。 细粒度性质引起的类间小变化和类内大变化使其成为一个具有挑战性的…...

节点导纳矩阵

节点导纳矩阵&#xff08;Node Admittance Matrix&#xff09;是电力系统分析中的关键工具&#xff0c;它用于描述电力系统中不同节点之间的电导和电纳参数。这个矩阵为电力工程师提供了深入了解电力系统运行和分析所需的数学工具。 节点导纳矩阵是一个复数矩阵&#xff0c;通常…...

小米真无线耳机 Air 2s产品蓝牙配对ubuntu20.04 笔记本电脑

小米真无线耳机 Air 2s产品蓝牙配对ubuntu20.04 笔记本电脑 1.我的笔记本是 22款联想拯救者y9000k&#xff0c;安装了双系统&#xff0c;ubuntu20.04。 2.打开耳机&#xff0c;按压侧面按钮2秒&#xff0c;指示灯显示白色闪烁。 3.打开ubunru20.04 系统右上角wifi的位置&…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...