跳转到主内容
极星编程网:以代码为星,赴技术山海!

Golang context怎么传递取消信号_Golang context取消教程【高效】

context.WithCancel 返回新 context 和 cancel 函数,调用 cancel 即标记完成并关闭 Done channel;WithTimeout 基于相对时间,WithDeadline 基于绝对时间且更抗系统时钟调整。 context 取消信号不是靠“传”出来的,而是靠
context.WithCancel
创建的父子关系联动生效的——你改了子 context 的状态,父 context 不会感知;但父 cancel 了,所有子自动失效。 为什么
context.WithCancel
返回两个值? 它返回一个新
context.Context
和一个
cancel
函数。这个
cancel
不是“发信号”,而是“触发关闭”:调用它,就立刻把该 context 标记为 Done,并关闭其
Done()
channel。 不调用
cancel()
,子 context 就永远不会结束,哪怕父 context 已 cancel(除非是
WithTimeout
这类带自动终止的) 多次调用同一个
cancel()
是安全的,但第二次起什么也不做 如果忘了 defer
cancel()
,会导致 goroutine 泄漏或资源长期占用(比如数据库连接、HTTP 连接)
context.WithTimeout
和
context.WithDeadline
的区别在哪? 两者都自动 cancel,但触发条件不同:
WithTimeout
是相对当前时间加偏移,
WithDeadline
是绝对时间点。选错会导致超时逻辑错乱。
context.WithTimeout(ctx, 5*time.Second)
:从调用那一刻起,5 秒后自动 cancel
context.WithDeadline(ctx, time.Now().Add(5*time.Second))
:效果看似一样,但若系统时间被 NTP 调整过,
WithDeadline
更可靠(它依赖 monotonic clock) 在 HTTP server 中,通常用
WithTimeout
;在定时任务或与外部服务约定截止时间时,
WithDeadline
更准 goroutine 里怎么正确监听取消? 不能只检查
ctx.Done()
是否关闭,还得处理
ctx.Err()
来区分是超时、取消,还是别的原因。 go语言参考手册 中文CHM版 Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译 下载 立即学习 “ go语言免费学习笔记(深入) ”; 永远用
select { case ,别用 if ctx.Err() != nil
—— 因为
Done()
channel 关闭后,
Err()
才有意义 在循环中监听时,每次迭代都要 select,否则可能卡死(比如网络读写阻塞时) 调用阻塞函数(如
http.Client.Do
、
time.Sleep
)前,确保它们本身支持 context(如用
http.NewRequestWithContext
),否则 cancel 无效 真正难的不是调用
WithCancel
,而是决定在哪里 call
cancel()
、什么时候该把它传进 goroutine、以及哪些地方必须主动检查
ctx.Err()
并清理资源——这些地方一漏,context 就只是个摆设。

相关文章