<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Context on buvidk's Blog</title><link>https://buvidk1234.github.io/tags/context/</link><description>Recent content in Context on buvidk's Blog</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Tue, 01 Sep 2026 00:10:00 +0800</lastBuildDate><atom:link href="https://buvidk1234.github.io/tags/context/index.xml" rel="self" type="application/rss+xml"/><item><title>Go Runtime（十一）：Context取消传播、Deadline与Cause</title><link>https://buvidk1234.github.io/posts/go-runtime-11-context/</link><pubDate>Tue, 01 Sep 2026 00:10:00 +0800</pubDate><guid>https://buvidk1234.github.io/posts/go-runtime-11-context/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文源码基线为 &lt;strong&gt;Go 1.26.2&lt;/strong&gt;。这是系列从 runtime 核心延伸到标准库并发机制的收束篇；&lt;code&gt;context&lt;/code&gt; 是标准库中的协作式取消协议，借助 Channel、锁、原子操作和 Timer 实现取消传播。源码链接固定到 &lt;code&gt;go1.26.2&lt;/code&gt; tag。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;context.Context&lt;/code&gt; 在请求调用链中传递三类信息：取消信号、截止时间和请求范围内的值。任务函数通过观察 &lt;code&gt;Done&lt;/code&gt;、返回错误和清理资源来响应取消。&lt;/p&gt;
&lt;p&gt;本文先建立公开契约和资源所有权，再沿最常见的标准取消树追踪 &lt;code&gt;WithCancel -&amp;gt; propagateCancel -&amp;gt; cancel&lt;/code&gt;。自定义 Context 的兼容路径作为边界补充，最后再解释 Deadline、Cause、AfterFunc、WithoutCancel 和 Value。&lt;/p&gt;
&lt;h2 id="context接口表达什么"&gt;Context接口表达什么&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/golang/go/blob/go1.26.2/src/context/context.go#L67"&gt;&lt;code&gt;Context&lt;/code&gt;&lt;/a&gt; 接口由四个方法组成：&lt;/p&gt;
&lt;details class="code-fold" open&gt;
&lt;summary&gt;GO&lt;/summary&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Context&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Deadline&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deadline&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="kd"&gt;chan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;any&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/details&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;回答的问题&lt;/th&gt;
&lt;th&gt;关键语义&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Deadline&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;截止时间及其设置状态&lt;/td&gt;
&lt;td&gt;返回时间和 &lt;code&gt;ok&lt;/code&gt; 标记&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Done&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;何时收到取消通知&lt;/td&gt;
&lt;td&gt;返回只读 Channel；永不取消时可以为 &lt;code&gt;nil&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Err&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;当前取消分类&lt;/td&gt;
&lt;td&gt;返回 &lt;code&gt;Canceled&lt;/code&gt;、&lt;code&gt;DeadlineExceeded&lt;/code&gt; 或 &lt;code&gt;nil&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Value&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;请求链上携带了什么值&lt;/td&gt;
&lt;td&gt;沿父链查找最近的同 key 值&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;Done&lt;/code&gt; 通过关闭 Channel 完成一对多广播，&lt;code&gt;Err&lt;/code&gt; 和 &lt;code&gt;Cause&lt;/code&gt; 提供取消原因。Context 支持多个 goroutine 并发调用；&lt;code&gt;Value&lt;/code&gt; 中对象的并发安全性由对象自身的同步机制保证。&lt;/p&gt;</description></item></channel></rss>