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

【golang-技巧】- context 使用

1.context是什么?

context.Context 是 Go 语言标准库中的一个类型,用于在多个 Goroutine 之间传递请求的上下文,以及控制请求的生命周期。Context 类型提供了一种机制,可以让程序在一个请求或操作被取消或超时时,及时释放资源或退出。以下是 context.Context 的作用、应用场景、最佳实践和代码实例。

context.Context 的主要作用是传递请求的上下文信息,并控制请求的生命周期。它可以用来传递请求的元数据、请求 ID、用户信息等,在多个 Goroutine 之间进行传递和访问。同时,Context 还可以用于控制请求的超时和取消,以及通知 Goroutine 关闭资源和退出程序。

Context 类型的应用场景比较广泛,包括但不限于以下几个方面:

Web 服务器:在 Web 服务器中,每个请求都可以创建一个 Context 对象,用于存储请求的元数据、用户信息等,并控制请求的生命周期和取消。
RPC 通信:在 RPC 通信中,可以使用 Context 对象传递请求的上下文信息,并控制请求的超时和取消。
数据库访问:在访问数据库时,可以使用 Context 对象传递数据库连接信息,并控制请求的超时和取消。
日志记录:在记录日志时,可以使用 Context 对象传递请求的元数据和用户信息等,方便后续查询和分析。

以下是一些使用 context.Context 的最佳实践:

传递 Context 对象时,应该显式传递,而不是通过全局变量或函数参数等方式传递。
在请求处理过程中,应该根据需要进行 Context 对象的传递和修改,以确保每个请求都有独立的 Context 对象。
在创建 Context 对象时,应该尽量设置超时和取消机制,以避免资源泄漏和程序挂起。
代码实例:

2.example

timeout

func TestExceedTime(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
	defer cancel()
	go func(ctx context.Context) {
		for {
			select {
			case <-ctx.Done():
				fmt.Println("context has cancel or timeout")
				return
			default:
				fmt.Println("process request")
				time.Sleep(time.Second)
			}
		}
	}(ctx)
	time.Sleep(time.Second * 10)

}

在上面的代码中,我们首先创建了一个带有超时和取消机制的 Context 对象 ctx,并传递给一个 Goroutine。在 Goroutine 中,我们模拟了一个耗时的操作,并使用 select 语句不断判断 Context 对象的状态,如果已经超时或取消,则退出 Goroutine。在主程序中,我们等待请求处理完成,然后退出程序。如果在 5 秒内请求处理完成,则输出“request processed successfully”;否则,输出“request canceled or timeout”。这个例子展示了如何使用 context.Context 进行超时和取消控制,避免 Goroutine 资源泄漏和程序挂起。

value

func TestCtxValue(t *testing.T) {
	ctx := context.WithValue(context.Background(), "name", "haha")
	name := ctx.Value("name")
	fmt.Println("name", name)

	ctx = context.WithValue(context.Background(), "name", "lala")
	name = ctx.Value("name")
	fmt.Println("name", name)
}

cancel

func TestCtxCancel(t *testing.T) {
	ctx, cancel := context.WithCancel(context.Background())

	go func(ctx context.Context) {
		time.Sleep(time.Second * 5)
		cancel()
	}(ctx)

	for {
		select {
		case <-ctx.Done():
			fmt.Println("ctx has cancel")
			os.Exit(-1)
		default:
			fmt.Println("has running")
			time.Sleep(time.Second)
		}
	}
}

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

相关文章:

  • 游戏行业趋势:“AI、出海、IP”大热下,如何提升竞争力?
  • 鸿蒙多线程开发——线程间数据通信对象01
  • 如何理解Lua 使用虚拟堆栈
  • 241120学习日志——[CSDIY] [InternStudio] 大模型训练营 [09]
  • 【 模型】 开源图像模型Stable Diffusion入门手册
  • 极客时间《Redis核心技术与实战》开篇词 知识点总结
  • spacy 安装 en_core_web_sm
  • MySQL中有哪几种锁?
  • Linux基础指令(汇总)
  • StarRocks 架构
  • Flutter:AnimatedPadding动态修改padding
  • 云原生之k8s服务管理
  • idea启动服务报错Application run failed
  • 目标驱动学习python动力
  • MySQL创建和管理触发器
  • (附项目源码)Java开发语言,215 springboot 大学生爱心互助代购网站,计算机毕设程序开发+文案(LW+PPT)
  • 常用命令集
  • vue2中引入cesium全步骤
  • MongoDB调优利器:掌握性能分析工具mongostat
  • 字节跳动青训营刷题笔记14
  • Spark 分布式计算中网络传输和序列化的关系(二)
  • leetcode - 2516. Take K of Each Character From Left and Right
  • 2024年亚太C题第二版本二问题1求解过程+代码运行以及问题2-4超详细思路分析
  • 第三百三十节 Java网络教程 - Java网络UDP服务器
  • uni-app快速入门(十)--常用内置组件(下)
  • 查看docker日志 journalctl -u docker.service