网站备案服务码口令是什么意思,济南建设工程,家居商城网站模板,小型企业网站建设旅游景点网论文文章目录 1、什么是Context2、Context的作用3、Context的解析3.1、Context的源码解析3.2、 context包中实现context接口的四种结构体类型3.2.1、emptyCtx3.2.2、cancelCtx3.2.3、timerCtx3.2.4、valueCtx 4、总结 1、什么是Context
Context是 Go 语言中的一个标准库#xff0… 文章目录 1、什么是Context2、Context的作用3、Context的解析3.1、Context的源码解析3.2、 context包中实现context接口的四种结构体类型3.2.1、emptyCtx3.2.2、cancelCtx3.2.3、timerCtx3.2.4、valueCtx 4、总结 1、什么是Context
Context是 Go 语言中的一个标准库用于在处理并发编程时提供对请求的截止时间、取消信号以及请求范围内共享数据的管理。它在多个 goroutine 之间传递是一种上下文管理工具。
Context 的主要目的是在不同的 goroutine 之间传递控制信号和数据。通过 Context你可以
设置请求的超时时间或截止时间。传递取消信号以便可以通知 goroutine 任务已经完成或需要停止。在多个 goroutine 之间共享值。
2、Context的作用 设想这样一种场景你正在开发一个 Web 应用当用户发送一个请求request后可能会启动多个 goroutine 来处理该请求的不同部分。如果单个请求的 goroutine 结构比较简单,处理起来也不麻烦,但是如果启动多个、深层次的 goroutine则会导致代码的复杂性和可维护性变得更加困难。而有了context,我们就可以通过它来管理这些 goroutine并在它们之间传递控制信号和数据。 Context 在这种场景中的作用主要体现在以下几个方面
取消信号传递处理用户请求的过程中可能会因为用户主动取消请求或请求超时而需要提前停止某些 goroutine 的执行。Context 提供了一种机制可以在多个 goroutine 之间传递取消信号当父 Context 取消时所有与之关联的子 goroutine 都会收到取消通知并可以安全地停止工作避免不必要的资源消耗。数据共享在处理用户请求时某些全局信息例如用户认证信息、追踪 ID 等需要在不同的 goroutine 之间共享。通过 Context这些数据可以被安全地传递而不需要通过全局变量或其他不安全的方式共享。这样可以保持代码的简洁性和安全性尤其在并发环境下避免数据竞争。超时控制在处理用户请求时可能会遇到一些耗时长的操作例如数据库查询或网络请求。Context 提供了一种机制可以设置超时时间当超时时间到达后Context 会自动取消相关的 goroutine避免资源占用过多。
除了上述作用外Context 还可以更高效地管理系统资源例如在请求超时或任务完成时主动释放资源避免资源浪费防止 goroutine 泄漏。
3、Context的解析
3.1、Context的源码解析
Context 实际上是一个定义了4个方法的接口,凡是实现了该接口的都称为一种 Context。
type Context interface {// 返回 context 的截止时间deadline表示任务应该在什么时候之前完成。// 如果没有设置截止时间就返回 false 和一个空的时间值。Deadline() (deadline time.Time, ok bool)//当 context 被取消或者超时时这个方法返回的 channel 会被关闭。通过监听这个信号可以决定是否要终止正在进行的任务。Done() -chan struct{}//这个方法用来返回 context 被取消的具体原因比如是因为超时、手动取消等通常会在 Done() 关闭后使用。Err() error// 从 context 中获取与某个 key 关联的数据用于在 goroutine 之间传递一些共享信息。// key 可以是任何类型用于区分不同的数据。Value(key interface{}) interface{}
}3.2、 context包中实现context接口的四种结构体类型
在context包中有四个结构体类型实现了Context接口分别是emptyCtx、cancelCtx、timerCtx和valueCtx。
3.2.1、emptyCtx
emptyCtx 是一个没有任何取消、截止时间或值的 Context它通常作为默认的上下文在创建顶级 Context 时使用。
解释 emptyCtx 实现了 Context 接口的所有方法但它们都返回默认值或 nil因此 emptyCtx是没有实际功能的。那么它存在的目的是什么呢?
原因是在 Go 的 Context 体系中Context 对象通常是分层次的即通过创建一个父 Context 来衍生出子 Context并在这些子 Context 中传递控制信号、共享数据等。因此为了构建这棵 Context 对象树我们需要一个基础的、没有任何附加信息的根节点。emptyCtx 正是为了提供这样一个基本的起点。 此外有时你在编写代码时需要一个 Context 占位符但暂时不确定具体的 Context 类型。这时你可以使用 context.TODO()它返回的实际上也是 emptyCtx。这样可以让代码先运行稍后再决定具体的 Context 实现。
总之emptyCtx 是一个没有任何功能的 Context它的使用场景有两个
用于顶层上下文作为 Context 对象树的根节点。作为占位符用于在编写代码时暂时不确定具体的 Context 类型。
注意这四种结构体中只有emptyCtx不需要通过已有context实例创建因此一个context树的根context一定是emptyCtx。
使用示例:
ctx : context.Background()
// 或者
ctx : context.TODO()
// 以下代码中ctx 就是一个空的上下文3.2.2、cancelCtx
cancelCtx 是带有取消功能的 Context它允许父 Context 取消并通知所有子 Context 和相关 goroutine。
解释
cancelCtx 通过 WithCancel 函数创建提供一种手动取消 Context 的机制。当调用 cancel() 函数时所有依赖此 Context 的子 goroutine 都会收到取消通知。Done() 方法会返回一个关闭的 channel表示 Context 已经被取消。
使用场景
用于主动取消某个操作比如超时、用户主动取消等。适用于请求处理被取消、提前终止任务等场景。
使用示例:
package mainimport (contextfmttime
)func main() {// 通过emptyCtx创建一个带有取消功能的上下文context.Background()创建的即为emptyCtxctx, cancel : context.WithCancel(context.Background())go func() {// 模拟执行任务for {select {case -ctx.Done(): // 接收到取消信号退出 goroutinefmt.Println(Task canceled)returndefault:fmt.Println(Task running...)time.Sleep(1 * time.Second)}}}()// 运行 3 秒后取消操作time.Sleep(3 * time.Second)cancel()// 给 goroutine 充分的时间来处理取消操作time.Sleep(1 * time.Second)
}
注意:当 Done() 信号触发时虽然上下文 Context 已经被取消但具体的 goroutine 或子进程是否终止取决于代码逻辑。cancel() 只是通知 goroutine Context 已被取消具体的退出逻辑需要我们手动处理。
3.2.3、timerCtx
timerCtx 是带有超时或截止时间Deadline的 Context当超过指定时间时Context 会自动取消。
解释
timerCtx 是通过 WithTimeout 或 WithDeadline 创建的。它允许你为 Context 设置一个时间限制当超时或达到截止时间时Context 会自动取消所有关联的 goroutine 都会收到取消通知。主要用于那些有执行时间限制的任务。
使用场景
当你需要控制某个任务的最大执行时间如网络请求、数据库操作等防止任务无限期地运行时使用 timerCtx。适用于设置请求超时、操作超时等场景。
使用示例:
// // 通过emptyCtx创建一个带有取消功能的上下文context.Background()创建的即为emptyCtx
ctx, cancel : context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()select {
case -time.After(3 * time.Second):fmt.Println(Task finished)
case -ctx.Done():fmt.Println(Timeout:, ctx.Err()) // 这里会输出超时的错误
}
3.2.4、valueCtx
valueCtx 是可以在 goroutine 之间传递键值对的 Context用于携带与请求相关的信息。context.WithValue() 可以将特定的值与某个 key 关联起来并且这个 key 通常是一个自定义类型而不是直接使用内置的 string 或 int 类型。
解释 valueCtx 是通过 WithValue 创建的用于在不同的 goroutine 之间传递一些与上下文相关的数据。这个数据可以通过 Context 的Value()方法获取。 context.WithValue() 可以将特定的值与某个 key 关联起来并且这个 key 通常是一个自定义类型而不是直接使用内置的数据类型如string 或 int 类型。
使用场景
适用于在多个 goroutine 之间传递一些共享信息如用户 ID、请求 ID 等。避免使用全局变量或复杂的依赖传递确保上下文中的数据和 goroutine 的生命周期一致。
使用示例:
type key stringfunc main() {ctx : context.WithValue(context.Background(), key(userID), 123)go func(ctx context.Context) {userID : ctx.Value(key(userID)) // 定义了一个新的类型 key底层类型为 stringfmt.Println(User ID:, userID)}(ctx)time.Sleep(1 * time.Second)
}注意在上述代码中如果直接使用 string 类型作为 key 很可能会出现 key 重名的情况。比如不同的模块可能会不小心使用相同的字符串 “userID” 作为 key 这会导致冲突。因此为了避免这种情况我们会创建一个自定义类型的 key 比如 type key string 。这样尽管它本质上仍然是字符串类型但它已经是一个新的类型这样就避免了潜在的冲突问题。
4、总结
Context 是 Go 语言中的一个标准库用于在处理并发编程时提供对请求的截止时间、取消信号以及请求范围内共享数据管理的管理。它在多个 goroutine 之间传递是一种上下文管理工具。
通过context包给出的四种结构体类型我们可以轻松实现对 goroutine 的管理
emptyCtx基础的空 Context没有取消、超时或值适合作为顶层 Context 使用。cancelCtx提供手动取消功能适合需要手动控制任务生命周期的场景。timerCtx带有超时或截止时间适合限制任务执行时间的场景。valueCtx允许传递数据适合跨 goroutine 传递少量与请求相关的上下文信息。