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