Go Context 简介

简介: Go Context 简介

Context


上下文 context.Context  Go 语言中用来设置截止日期,同步信号,传递请求相关的结构体,context 与 gotoutine 有比较密切的关系,是 Go 语言中的独特设计。

image.png

Context 作用


  • 每个 Context 都会从最顶层 Goroutine 一层一层传递到最下层,context.Context 可以在上层 Goroutine 执行出现错误,会将信号及时同步到下一次层,这样,上层因为某些原因失败时, 下层就可以停掉无用的工作,以减少资源损耗。实际应用:RPC 超时时间设置
  • context 中一般意义 context.WithValue 能从父上下文中创建一个子上下文,传值的子上下文使用 context.valueCtx 类型。WithValue 是一对 kv 类型,可用来传值,实际应用:传递全局唯一的调用链

Context 接口


Context 是 Go 语言在 1.7 版本引入的标准库接口,有以下需要实现的方法

  1. Deadlime 返回 context.Context 被取消的时间,也就是完成工作的截止时间
  2. Done 返回一个 Channel ,这个 Channel 会在当前工作完成或者被取消后关闭,多次调用 Done 方法会返回同一个Channle
  3. Err 返回 context.Context 结束的原因,只会在 Done 方法对应的 Channel 关闭时返回非空的值
  4. Value 从 context.Context 中获取对应的值,对同一个上下文来说,多次调用 Value 并传入相同的 Key 会返回相同的结果。该方法可以用来传递特定的请求。
  • 如果 context.Context 被取消,会返回 Canceled 错误;
  • 如果 context.Context 超时,会返回 DeadlineExceeded 错误;
type Context interface {
 Deadline() (deadline time.Time, ok bool)
 Done() <-chan struct{}
 Err() error
 Value(key interface{}) interface{}
}

image.png

使用 context 同步信号


创建一个过期时间为 1s 的上下文, 并向上下文传入 handle 函数,该方法会使用 500ms 的时间处理传入的请求。

package contexttest
import (
 "context"
 "fmt"
 "testing"
 "time"
)
func TestContext(t *testing.T) {
 // 创建一个过期时间为1s的上下文
 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
 defer cancel()
 go handle(ctx, 500*time.Millisecond)
 select {
 case <-ctx.Done():
  fmt.Println("main", ctx.Err())
 }
}
func handle(ctx context.Context, duration time.Duration) {
 select {
 case <-ctx.Done():
  fmt.Println("handle", ctx.Err())
 case <-time.After(duration):
  fmt.Println("process request with",
   duration)
 }
}


运行结果:


=== RUN   TestContext
process request with 500ms
main context deadline exceeded
--- PASS: TestContext (1.00s)
PASS

Context 创建


  • 根 Context: 通过 context.Backgroud() 创建
  • 子 Conetxt:context.WithCancel(parentConetxt) 创建
ctx, cancel := context.WithCancel(conetext.Background())
  • 当前 Context 被取消时,其他的子 context 都会被取消
  • 接收取消通知 <- ctx.Done()


测试代码package main


import (
 "context"
 "testing"
 "time"
)
func isCanceled(ctx context.Context) bool {
 select {
 case <-ctx.Done():
  return true
 default:
  return false
 }
}
func TestCanceledByConetxt(t *testing.T) {
 ctx, cancel := context.WithCancel(context.Background())
 for i := 0; i < 5; i++ {
  go func(i int, ctx context.Context) {
   for {
    if isCanceled(ctx) {
     break
    }
   }
   time.Sleep(time.Second * 1)
  }(i, ctx)
 }
 cancel()
}
相关文章
|
6月前
|
Java Go 开发者
Docker容器技术简介及其与Go语言的结合点
【2月更文挑战第23天】本文首先概述了Docker容器技术的核心概念和优势,接着探讨了Go语言与Docker容器技术的结合点。通过阐述Docker的轻量级、可移植性和版本控制等特性,以及Go语言在容器化应用中的优势,本文旨在说明两者结合能够实现更高效、灵活的应用开发和部署。
|
5月前
|
Go
go语言并发编程(五) ——Context
go语言并发编程(五) ——Context
|
1月前
|
存储 Go 数据库
Go语言Context包源码学习
【10月更文挑战第21天】Go 语言中的 `context` 包用于在函数调用链中传递请求上下文信息,支持请求的取消、超时和截止时间管理。其核心接口 `Context` 定义了 `Deadline`、`Done`、`Err` 和 `Value` 方法,分别用于处理截止时间、取消信号、错误信息和键值对数据。包内提供了 `emptyCtx`、`cancelCtx`、`timerCtx` 和 `valueCtx` 四种实现类型,满足不同场景需求。示例代码展示了如何使用带有超时功能的上下文进行任务管理和取消。
|
3月前
|
中间件 Go 数据库
slog 简介:用于 Go 的结构化日志
slog 简介:用于 Go 的结构化日志
|
3月前
|
存储 SQL Go
一文弄懂Go语言的Context包,值得收藏!
在开发高效的Go应用程序时,处理超时、取消操作和传递请求范围的数据至关重要。Go标准库中的`context`包提供了一套强大的工具,用于在不同层级间传递取消信号、超时和截止时间等信息。本文首先概述了`context`包的核心功能,接着详细介绍了关键方法,如`WithCancel`、`WithDeadline`、`WithTimeout`和`WithValue`的使用场景。通过创建和派生上下文,开发者能更好地管理请求的生命周期,控制长时间运行的操作,并在并发环境中传递必要的数据。
53 1
|
5月前
|
消息中间件 存储 Kafka
go语言并发实战——日志收集系统(二) Kafka简介
go语言并发实战——日志收集系统(二) Kafka简介
119 1
|
6月前
|
数据管理 Go 开发者
Golang深入浅出之-Go语言上下文(context)包:处理取消与超时
【4月更文挑战第25天】Go语言中的`context`包在并发、网络请求和长任务中至关重要,提供取消、截止时间和元数据管理。本文探讨`context`基础,如`Background()`、`TODO()`、`WithCancel()`、`WithDeadline()`和`WithTimeout()`。常见问题包括不当传递、过度使用`Background()`和`TODO()`以及忽略错误处理。通过取消和超时示例,强调正确传递上下文、处理取消错误和设置超时以提高应用健壮性和响应性。正确使用`context`是构建稳定高效Go应用的关键。
104 1
|
6月前
|
Go 开发者
Golang深入浅出之-Go语言上下文(context)包:处理取消与超时
【4月更文挑战第23天】Go语言的`context`包提供`Context`接口用于处理任务取消、超时和截止日期。通过传递`Context`对象,开发者能轻松实现复杂控制流。本文解析`context`包特性,讨论常见问题和解决方案,并给出代码示例。关键点包括:1) 确保将`Context`传递给所有相关任务;2) 根据需求选择适当的`Context`创建函数;3) 定期检查`Done()`通道以响应取消请求。正确使用`context`包能提升Go程序的控制流管理效率。
65 1
|
6月前
|
安全 Go 开发者
Golang深入浅出之-Go语言并发编程面试:Goroutine简介与创建
【4月更文挑战第22天】Go语言的Goroutine是其并发模型的核心,是一种轻量级线程,能低成本创建和销毁,支持并发和并行执行。创建Goroutine使用`go`关键字,如`go sayHello(&quot;Alice&quot;)`。常见问题包括忘记使用`go`关键字、不正确处理通道同步和关闭、以及Goroutine泄漏。解决方法包括确保使用`go`启动函数、在发送完数据后关闭通道、设置Goroutine退出条件。理解并掌握这些能帮助开发者编写高效、安全的并发程序。
89 1
|
6月前
|
存储 Java Go
编程笔记 GOLANG基础 002 Go语言简介
编程笔记 GOLANG基础 002 Go语言简介