<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Context on Chen Shungen</title><link>https://chenshungen.cn/tags/context/</link><description>Recent content in Context on Chen Shungen</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Mon, 20 Apr 2026 13:00:00 +0800</lastBuildDate><atom:link href="https://chenshungen.cn/tags/context/index.xml" rel="self" type="application/rss+xml"/><item><title>Go 并发原语 - Context</title><link>https://chenshungen.cn/blog/golang-concurrency/golang-context/</link><pubDate>Mon, 20 Apr 2026 13:00:00 +0800</pubDate><guid>https://chenshungen.cn/blog/golang-concurrency/golang-context/</guid><description>&lt;p>并发编程中，除了&amp;quot;互斥访问&amp;quot;和&amp;quot;等待通知&amp;quot;之外，还有一类核心需求——&lt;strong>取消和超时控制&lt;/strong>。比如：HTTP 请求超时了，下游所有 goroutine 都应该停止工作；用户取消了操作，正在进行的数据库查询应该被中断。Go 标准库的 &lt;code>context&lt;/code> 包就是为了解决这类问题而生的。&lt;/p>
&lt;h2 id="一context-解决什么问题">一、Context 解决什么问题？&lt;/h2>
&lt;p>假设一个 HTTP 请求触发了多个 goroutine 并行处理：&lt;/p>
&lt;div class="highlight-wrapper">
 &lt;button class="copy-code-btn" type="button" aria-label="Copy code to clipboard">
 &lt;svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
 &lt;rect x="9" y="9" width="13" height="13" rx="2" ry="2">&lt;/rect>
 &lt;path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">&lt;/path>
 &lt;/svg>
 &lt;span class="copy-text">Copy&lt;/span>
 &lt;/button>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl"> HTTP 请求
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ├── goroutine: 查询数据库
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ├── goroutine: 调用下游 API
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> └── goroutine: 读取缓存&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>
&lt;p>如果请求超时了（比如客户端断开连接），这三个 goroutine 应该如何知道&amp;quot;不用干了&amp;quot;？&lt;/p>
&lt;div class="highlight-wrapper">
 &lt;button class="copy-code-btn" type="button" aria-label="Copy code to clipboard">
 &lt;svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
 &lt;rect x="9" y="9" width="13" height="13" rx="2" ry="2">&lt;/rect>
 &lt;path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">&lt;/path>
 &lt;/svg>
 &lt;span class="copy-text">Copy&lt;/span>
 &lt;/button>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">没有 Context： 有 Context：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 请求超时 请求超时
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> │ │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> │ 数据库查询还在跑... │── ctx.Done() 触发
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> │ 下游 API 还在等... │── 所有 goroutine 收到信号
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> │ 缓存读取还在等... │── 立即停止，释放资源
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> │ │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> └── 资源浪费 💀 └── 干净退出 ✅&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>
&lt;p>Context 提供了三个核心能力：&lt;/p></description></item></channel></rss>