<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Channel on Chen Shungen</title><link>https://chenshungen.cn/tags/channel/</link><description>Recent content in Channel on Chen Shungen</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Mon, 20 Apr 2026 14:00:00 +0800</lastBuildDate><atom:link href="https://chenshungen.cn/tags/channel/index.xml" rel="self" type="application/rss+xml"/><item><title>Go 并发原语 - Channel</title><link>https://chenshungen.cn/blog/golang-concurrency/golang-channel/</link><pubDate>Mon, 20 Apr 2026 14:00:00 +0800</pubDate><guid>https://chenshungen.cn/blog/golang-concurrency/golang-channel/</guid><description>&lt;p>Channel 是 Go 语言内建的 &lt;strong>first-class 类型&lt;/strong>，也是 Go 与众不同的特性之一。它不是通过库提供的——而是直接内置在语言规范中，地位之高在编程语言中比较罕见。Channel 的设计源自 CSP（Communicating Sequential Process）模型：&lt;strong>不要通过共享内存来通信，要通过通信来共享内存。&lt;/strong>&lt;/p>
&lt;h2 id="一channel-基本用法">一、Channel 基本用法&lt;/h2>
&lt;h3 id="声明和初始化">声明和初始化&lt;/h3>
&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-go" data-lang="go">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// 声明&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">ch&lt;/span> &lt;span class="kd">chan&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="c1">// 双向 channel&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">sendCh&lt;/span> &lt;span class="kd">chan&lt;/span>&lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="c1">// 只发送&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">recvCh&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span>&lt;span class="kd">chan&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="c1">// 只接收&lt;/span>
&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 class="c1">// 初始化（必须用 make）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">ch&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nb">make&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kd">chan&lt;/span> &lt;span class="kt">int&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1">// 无缓冲&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">ch&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nb">make&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kd">chan&lt;/span> &lt;span class="kt">int&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">10&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1">// 有缓冲，容量 10&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>
&lt;h3 id="三种操作">三种操作&lt;/h3>
&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">┌──────────────────────────────────────────────────────────────┐
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ Channel 的三种操作 │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├──────────────────────────────────────────────────────────────┤
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ ch &amp;lt;- value 发送：把 value 放入 channel │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ value := &amp;lt;-ch 接收：从 channel 取出值 │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ close(ch) 关闭：关闭 channel │
&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;h3 id="无缓冲-vs-有缓冲">无缓冲 vs 有缓冲&lt;/h3>
&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">无缓冲 channel (make(chan int))：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 发送者 channel 接收者
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> │ │ │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> │── send ────→ │ │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> │ (阻塞...) │ │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> │ │ ←── recv ────────│
&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"> 发送和接收必须同时就绪，类似&amp;#34;面对面交接&amp;#34;。
&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">有缓冲 channel (make(chan int, 3))：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 发送者 buffer [_ _ _] 接收者
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> │ │ │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> │── send ────→ [v _ _] (不阻塞) │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> │── send ────→ [v v _] (不阻塞) │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> │── send ────→ [v v v] (不阻塞) │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> │── send ────→ [v v v] (阻塞! 满了) │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> │ │ ←── recv ────────│
&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"> 缓冲未满时发送不阻塞，缓冲为空时接收阻塞。&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/div>
&lt;h2 id="二channel-的行为表">二、Channel 的行为表&lt;/h2>
&lt;p>对 channel 执行不同操作，在不同状态下的行为：&lt;/p></description></item></channel></rss>