- 生命周期不同:Context 类型的上下文是有生命周期的,可以通过
context.WithCancel()
、context.WithDeadline()
或context.WithTimeout()
等函数来创建上下文,当上下文被取消或者超时时,其中的数据也会被销毁。而一个普通的 map 定义为全局变量,生命周期就与整个应用程序相同,除非应用程序退出,否则其中的数据是不会被销毁的。 - 并发安全性不同:Context 类型的上下文是并发安全的,可以在多个 goroutine 中共享使用。而一个普通的 map 定义为全局变量,如果在多个 goroutine 中同时读写可能会产生数据竞争和其他并发问题。
- 上下文值的语义不同:Context 类型的上下文中存储的是请求范围内的元数据和取消信号,例如请求 ID、用户认证信息、跟踪信息等。而一个普通的 map 可以存储任意类型的键值对,语义不够清晰。
在 Go 语言中,Context
类型的实现是并发安全的。这是因为 Context
类型内部使用了线程安全的数据结构,可以在多个 goroutine 中同时访问和修改。
具体来说,Context
类型内部使用了一个包含多个字段的结构体,其中包括一个父上下文指针、一个超时时间、一个取消函数、一个值、一个互斥锁等。这些字段都是线程安全的,可以在多个 goroutine 中同时访问和修改。
当一个 goroutine 调用 WithCancel()
或 WithTimeout()
等函数创建一个新的 Context
对象时,这个新的 Context
对象会继承父上下文的超时时间和取消函数等属性,并创建一个新的取消函数。这个取消函数会通知所有与该上下文对象相关联的 goroutine 停止执行。
在使用 Context
类型时,不同的 goroutine 可以使用 WithCancel()
或 WithTimeout()
等函数创建自己的子上下文对象,并将其传递给需要使用上下文的函数,这些函数就可以通过上下文对象获取超时时间、取消函数等属性,以及在需要时取消操作。
因为 Context
类型内部使用了线程安全的数据结构,并且实现了有效的上下文传递和取消机制,所以可以安全地在多个 goroutine 中同时使用,保证并发安全。