我的编程空间,编程开发者的网络收藏夹
学习永远不晚

golang如何去除context的deadline

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

golang如何去除context的deadline

golang 去除 context 的 deadline

背景

在使用 context 的时候遇到了开协程处理任务的情况,但是直接在协程里使用主线程的 context 会导致当主线程返回时协程任务也会因为 context cancel 而失败。
本文提供了两种办法可以取消掉 context 里的 timeout 和 deadline,再设置一个新的 timeout 上去。

方法一,创建一个新 context

最简单的方案是通过创建一个新的 context 来解决这个问题。

func main() {
	ctx := context.WithValue(context.Background(), "trace", "123")
	ctx, cancel := context.WithTimeout(ctx, time.Second)
	defer cancel()

	go func(ctx context.Context) {
		newCtx := context.WithValue(context.Background(), "trace", ctx.Value("trace"))
		// do something with newCtx
	}(ctx)

	fmt.Println("main finished")
}

但是这种方案有一个缺点,当生成一个新的 context 的时候,需要手动把老 context 中的 value 手动拿出来,再设置到新的里面去。 但是在很多情况下,这个 context 是上游传过来的,并不知道 value 里面有哪些具体的 key。或者里面的 value 过多,写起来很麻烦。

方法二,使用自定义结构体

通过看 context 的源码,其实可以发现 context 是一个 interface,这就给了我们操作的空间。

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

Context 是通过 Deadline() 这个函数控制整个 ctx 是否超时了的。那么我们就可以通过重写这个函数来规避超时。

// contextWithoutDeadline 伪造了一个没有 deadline 的 context
type contextWithoutDeadline struct {
	ctx context.Context
}

func (*contextWithoutDeadline) Deadline() (time.Time, bool) {
	return time.Time{}, false
}

func (*contextWithoutDeadline) Done() <-chan struct{} {
	return nil
}

func (*contextWithoutDeadline) Err() error {
	return nil
}

func (l *contextWithoutDeadline) Value(key interface{}) interface{} {
	return l.ctx.Value(key)
}

// DetachDeadline 从 context 剥离 deadline
func DetachDeadline(ctx context.Context) context.Context {
	return &contextWithoutDeadline{ctx: ctx}
}

// SetNewTimeout 设置新的超时时间
func SetNewTimeout(ctx context.Context, timeout time.Duration) (context.Context, context.CancelFunc) {
	return context.WithTimeout(DetachDeadline(ctx), timeout)
}

可以通过 DetachDeadline() 方法来将原 ctx 的 deadline 取消掉,或者直接通过 SetNewTimeout 的方法设置一个新的超时时间上去。

演示

func main() {
	ctx, _ := context.WithTimeout(context.Background(), time.Duration(10)*time.Second)
	fmt.Println(ctx.Deadline())

	newCtx := contextwarp.DetachDeadline(ctx)
	fmt.Println(newCtx.Deadline())

	newCtx2, _ := contextwarp.SetNewTimeout(ctx, time.Duration(1)*time.Second)
	fmt.Println(newCtx2.Deadline())
}

符合预期。

到此这篇关于golang如何去除 context 的 deadline的文章就介绍到这了,更多相关go去除 context 的 deadline内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

golang如何去除context的deadline

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

golang如何去除 context 的 deadline

去除Go中context的deadlineGo中的context可用于传递取消和超时信息,通常包含一个deadline。本文提供了四种方法来去除context的deadline,允许context无限制运行。这些方法包括:使用WithTimeout创建新context、使用WithDeadline创建新context、使用WithCancel创建新context以及使用Raw从现有context中移除deadline。去除deadline后,context将无法被取消或超时,应仅在明确需要时使用。
golang如何去除 context 的 deadline
2024-04-23

golang如何去除context的deadline

在使用context的时候遇到了开协程处理任务的情况,但是直接在协程里使用主线程的context会导致当主线程返回时协程任务也会因为contextcancel而失败,本文提供了两种办法可以取消掉context里的timeout和deadline,再设置一个新的timeout上去
2023-03-21

golang怎么去除context的deadline

今天小编给大家分享一下golang怎么去除context的deadline的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。go
2023-07-05

GoLang context包如何使用

本文小编为大家详细介绍“GoLang context包如何使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“GoLang context包如何使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。背景在父子协程协作
2023-07-05

thinkphp如何去除bom

这篇“thinkphp如何去除bom”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“thinkphp如何去除bom”文章吧。t
2023-07-04

如何去除php中的deprecated

本篇内容介绍了“如何去除php中的deprecated”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!php去除deprecated的方法:1
2023-06-25

php如何去除utf8的符号

本文小编为大家详细介绍“php如何去除utf8的符号”,内容详细,步骤清晰,细节处理妥当,希望这篇“php如何去除utf8的符号”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。php去除utf8符号的方法:1、创建
2023-07-04

php如何去除多余的0

这篇文章主要介绍php如何去除多余的0,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!在php中可以直接通过“floatval()”函数去除多余的0,该函数可以保留有效的小数点,也可以去掉后面多余的0,其语法是“flo
2023-06-08

php如何去除警告

这篇文章给大家分享的是有关php如何去除警告的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。php去除警告的方法:首先打开PHP页面文件;然后在php页面的开头部分加上“ini_set("display_error
2023-06-14

css如何去除table的间隙

本文将为大家详细介绍“css如何去除table的间隙”,内容步骤清晰详细,细节处理妥当,而小编每天都会更新不同的知识点,希望这篇“css如何去除table的间隙”能够给你意想不到的收获,请大家跟着小编的思路慢慢深入,具体内容如下,一起去收获
2023-06-06

php如何去除括号

这篇文章主要介绍php如何去除括号,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!php去除括号的方法:首先创建一个PHP示例文件;然后声明一个含有括号的变量;最后通过“str_replace(array( (, )
2023-06-14

photoshop水印如何去除

这篇文章主要介绍了photoshop水印如何去除的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇photoshop水印如何去除文章都会有所收获,下面我们一起来看看吧。ps去水印的方法:方法一: 1、首先通过左上角
2023-07-01

如何去除forum.php尾巴

去除forum.php尾巴的步骤:1、创建一个名为“.htaccess”的文件或者“web.config”文件;2、使用“.RewriteEngine On”指令设立重定向的条件;3、将“.htaccess”文件上传到你的网站根目录即可。本
2023-07-10

php如何去除斜线

这篇文章主要讲解了“php如何去除斜线”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“php如何去除斜线”吧!php去除斜线的方法:首先创建一个PHP示例文件;然后通过“stripslashe
2023-06-20

javascript如何去除空格

这篇文章主要介绍了javascript如何去除空格,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。JavaScript可以做什么1.可以使网页具有交互性,例如响应用户点击,给用
2023-06-14

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录