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

golang - context.Context:Goroutine数据传输和管理

context.Context是Go语言标准库中提供的一种用于管理goroutine生命周期和传递请求相关元数据的机制。

context.Context的主要作用和使用方法:

1. 截止时间和超时

Context可以设置一个截止时间或超时时间,当到达这个时间点时,Context会自动发出取消信号,通知相关的goroutine停止当前操作。这对于长时间运行的操作非常有用,可以避免资源浪费。

2. 取消信号

Context可以被手动取消,这会向所有相关的goroutine发送取消信号。这样可以让程序优雅地处理长时间运行的任务,而不会让它们无谓地消耗资源。

3. 请求相关数据

Context可以用于在goroutine之间传递与请求相关的数据,比如用户ID、请求ID等。这有助于跟踪和诊断问题。

4. goroutine生命周期管理

Context被取消或超时时,所有相关的goroutine都应该及时退出。这可以避免资源泄漏和无谓的计算。

使用context.Context的典型模式如下:

  1. 在程序入口点(如main函数)创建一个根Context
  2. 当需要启动新的goroutine时,可以从根Context派生出子Context,并将其传递给新的goroutine。
  3. 当需要取消或设置截止时间时,可以调用子Contextcancel()WithDeadline()方法。
  4. 在goroutine中,可以使用context.WithValue()Context中存储和读取请求相关的数据。

总之,context.Context是Go语言并发编程中非常重要的一个概念,它提供了一种优雅的方式来管理goroutine的生命周期,并在goroutine之间传递上下文信息。

下面是一个使用 context.Context 的具体 Go 代码示例:

package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	// 步骤 1: 在程序入口点创建一个根 Context
	rootCtx := context.Background()

	// 步骤 2: 从根 Context 派生出子 Context,并传递给新的 goroutine
	childCtx, cancel := context.WithTimeout(rootCtx, 5*time.Second)
	defer cancel() // 确保 Context 在函数退出时被取消

	// 在新的 goroutine 中执行任务
	go doWork(childCtx)

	// 等待任务完成或超时
	select {
	case <-childCtx.Done():
		if childCtx.Err() != nil {
			fmt.Println("任务执行失败:", childCtx.Err())
		} else {
			fmt.Println("任务执行成功")
		}
	}
}

func doWork(ctx context.Context) {
	// 步骤 4: 在 goroutine 中使用 context.WithValue() 存储请求相关数据
	newCtx := context.WithValue(ctx, "requestID", "12345")

	// 模拟一个耗时的操作
	fmt.Println("开始执行任务...")
	time.Sleep(3 * time.Second)

	// 步骤 3: 检查 Context 是否被取消或超时
	select {
	case <-ctx.Done():
		fmt.Println("任务被取消或超时:", ctx.Err())
		return
	default:
		// 任务执行逻辑
		requestID := ctx.Value("requestID").(string)
		fmt.Println("任务执行成功, requestID:", requestID)
	}
}

这个示例展示了使用 context.Context 的典型模式:

  1. main 函数中,我们创建了一个根 Context 对象 rootCtx
  2. 我们从根 Context 派生出一个子 Context childCtx,并设置了 5 秒的超时时间。同时我们获取了 cancel 函数,以便在函数退出时取消 Context
  3. 我们启动了一个新的 goroutine,并将 childCtx 传递给 doWork 函数。
  4. doWork 函数中,我们使用 context.WithValue()Context 中存储了一个请求 ID。
  5. 在模拟的耗时操作中,我们检查 Context 是否被取消或超时。如果是,我们打印出错误信息并返回。
  6. 如果任务执行成功,我们从 Context 中读取请求 ID 并打印出来。

http://www.kler.cn/a/500197.html

相关文章:

  • [免费]微信小程序(高校就业)招聘系统(Springboot后端+Vue管理端)【论文+源码+SQL脚本】
  • Notepad++上NppFTP插件的安装和使用教程
  • JS爬虫实战演练
  • 3DGabor滤波器实现人脸特征提取
  • Swagger学习⑰——@Link注解
  • Golang 设计模式
  • 自动化测试框架playwright 常见问题和解决方案!
  • Caffeine核心设计图解
  • SQL-leetcode-584. 寻找用户推荐人
  • 网络安全行业规划,零基础如何入门网络渗透?
  • 拥抱HarmonyOS之高效使用DevEco
  • 中阳智能量化交易模型:科技驱动的投资革命
  • linux网络 | https前置知识 | 数据加密与解密、数据摘要
  • 继续坚持与共勉
  • openstack下如何生成centos9 centos10 和Ubuntu24 镜像
  • Linux 免杀
  • leetcode 483. 最小好进制
  • 《Opencv》图像的旋转
  • Android车机DIY开发之学习篇(五)默认应用修改
  • 【网络安全 SOC】痛苦金字塔 Pyramid Of Pain
  • python中无法引入pil怎么解决
  • Openstac持久存储之块存储cinder
  • 机器学习之决策树的分类树模型及决策树绘制