Back to home

Context 类型和普通定义一个 map 来进行全局变量区别

7 min read
  1. 生命周期不同:Context 类型的上下文是有生命周期的,可以通过 context.WithCancel()context.WithDeadline()context.WithTimeout() 等函数来创建上下文,当上下文被取消或者超时时,其中的数据也会被销毁。而一个普通的 map 定义为全局变量,生命周期就与整个应用程序相同,除非应用程序退出,否则其中的数据是不会被销毁的。
  2. 并发安全性不同:Context 类型的上下文是并发安全的,可以在多个 goroutine 中共享使用。而一个普通的 map 定义为全局变量,如果在多个 goroutine 中同时读写可能会产生数据竞争和其他并发问题。
  3. 上下文值的语义不同:Context 类型的上下文中存储的是请求范围内的元数据和取消信号,例如请求 ID、用户认证信息、跟踪信息等。而一个普通的 map 可以存储任意类型的键值对,语义不够清晰。

在 Go 语言中,Context 类型的实现是并发安全的。这是因为 Context 类型内部使用了线程安全的数据结构,可以在多个 goroutine 中同时访问和修改。

具体来说,Context 类型内部使用了一个包含多个字段的结构体,其中包括一个父上下文指针、一个超时时间、一个取消函数、一个值、一个互斥锁等。这些字段都是线程安全的,可以在多个 goroutine 中同时访问和修改。

当一个 goroutine 调用 WithCancel()WithTimeout() 等函数创建一个新的 Context 对象时,这个新的 Context 对象会继承父上下文的超时时间和取消函数等属性,并创建一个新的取消函数。这个取消函数会通知所有与该上下文对象相关联的 goroutine 停止执行

在使用 Context 类型时,不同的 goroutine 可以使用 WithCancel()WithTimeout() 等函数创建自己的子上下文对象,并将其传递给需要使用上下文的函数,这些函数就可以通过上下文对象获取超时时间、取消函数等属性,以及在需要时取消操作。

因为 Context 类型内部使用了线程安全的数据结构,并且实现了有效的上下文传递和取消机制,所以可以安全地在多个 goroutine 中同时使用,保证并发安全。