<?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 Kingcanfish 的小星球 🪐</title>
        <link>https://blog.gxy.plus/tags/channel/</link>
        <description>Recent content in Channel on Kingcanfish 的小星球 🪐</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh</language>
        <copyright>Kingcanfish. All rights reserved.</copyright>
        <lastBuildDate>Thu, 11 Jun 2020 14:31:00 +0800</lastBuildDate><atom:link href="https://blog.gxy.plus/tags/channel/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>Go的channel 的小学习</title>
            <link>https://blog.gxy.plus/posts/gochannel/</link>
            <pubDate>Thu, 11 Jun 2020 14:31:00 +0800</pubDate>
            <guid>https://blog.gxy.plus/posts/gochannel/</guid>
            <description>&lt;h2 id=&#34;channel&#34;&gt;channel&#xA;&lt;/h2&gt;&lt;p&gt;GO 语言的 channel  是一个比较神奇的东西，也可以说在 go 协程通信里面是不可或缺的一部分，现在就整理一下channel 相关的知识，下面的内容并非所有都是原创，只是简单的说一下可能比较重要的地方  具体的用法我也不多说，网上的教程很多&lt;/p&gt;&#xA;&lt;p&gt;源码如下，位置在  &lt;code&gt; src/runtime/chan.go&lt;/code&gt;&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;hchan&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;qcount&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// total data in the queue&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;dataqsiz&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// size of the circular queue&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;buf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;unsafe&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Pointer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// points to an array of dataqsiz elements&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;elemsize&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint16&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;closed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;elemtype&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;_type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// element type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;sendx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// send index&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;recvx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uint&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// receive index&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;recvq&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;waitq&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// list of recv waiters&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;sendq&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;waitq&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// list of send waiters&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// lock protects all fields in hchan, as well as several&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// fields in sudogs blocked on this channel.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&#x9;// Do not change another G&amp;#39;s status while holding this lock&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// (in particular, do not ready a G), as this can deadlock&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// with stack shrinking.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;lock&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;mutex&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;waitq&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;first&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;sudog&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;last&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;sudog&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;qcount&lt;/code&gt;  是 chan 中已有元素的数量， &lt;code&gt;dataqsiz&lt;/code&gt; 循环队列的 节点数&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;buf&lt;/code&gt; 是一个 循环队列，缓冲区&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;sendx&lt;/code&gt; 为写入数据的索引位，之后的数据写在环形队列的这个索引位置上；&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;recvx&lt;/code&gt; 读取数据的索引位下一次读取数据就从这个位置开始读取&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;elemtype&lt;/code&gt; chan 元素类型， 一个chan 只可以有一种类型&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;recvq&lt;/code&gt; 读取的 goroutine ( 源码里成为G，我觉得大概是一个意思) 的阻塞队列; &lt;code&gt;sendq&lt;/code&gt; 是写入 chan 的 goroutine 的阻塞队列&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;lock&lt;/code&gt; 互斥锁，不允许并发读写,仅允许一个goroutine 进行操作，也就是说串行的&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;elemsize&lt;/code&gt; 代表类型大小，方便在缓冲队列中定位元素的位置&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;向-channel-写数据&#34;&gt;向 channel 写数据&#xA;&lt;/h2&gt;&lt;p&gt;简单过程如下：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;如果等待接收队列recvq不为空，说明缓冲区中没有数据或者没有缓冲区，此时直接从recvq取出G,并把数据写入，最后把该G唤醒，结束发送过程&lt;/li&gt;&#xA;&lt;li&gt;如果缓冲区中有空余位置，将数据写入缓冲区，结束发送过程&lt;/li&gt;&#xA;&lt;li&gt;如果缓冲区中没有空余位置，将待发送数据写入 G，将当前G加入 &lt;code&gt;sendq&lt;/code&gt;，进入睡眠，等待被读 goroutine 唤醒&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://static.guoxy.top/img/chan-03-send_data.png&#34;  /&gt;&#xA;&lt;h2 id=&#34;向-channel-读数据&#34;&gt;向 Channel 读数据&#xA;&lt;/h2&gt;&lt;ol&gt;&#xA;&lt;li&gt;如果等待发送队列 &lt;code&gt;sendq&lt;/code&gt; 不为空，且没有缓冲区，直接从 &lt;code&gt;sendq&lt;/code&gt; 中取出G，把G中数据读出，最后把G唤醒，结束读取&lt;/li&gt;&#xA;&lt;li&gt;如果等待发送队列 &lt;code&gt;sendq&lt;/code&gt; 不为空，此时说明缓冲区已满，从缓冲区中首部读出数据，把发送队列第一个G的数据写入缓冲区尾部，把G唤醒，结束读取过程&lt;/li&gt;&#xA;&lt;li&gt;如果等待发送队列 &lt;code&gt;sendq&lt;/code&gt; 为空，但是缓冲区中有数据，则从缓冲区取出数据，结束读取过程&lt;/li&gt;&#xA;&lt;li&gt;如果等待发送队列 &lt;code&gt;sendq&lt;/code&gt; 为空，且缓冲区没数据 ，将当前 &lt;code&gt;goroutine&lt;/code&gt; 加入 &lt;code&gt;recvq&lt;/code&gt;，进入睡眠，等待被写 &lt;code&gt;goroutine&lt;/code&gt; 唤醒&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;举个例子&#34;&gt;举个例子&#xA;&lt;/h2&gt;&lt;p&gt;拿 餐厅的厨师，窗口， 服务员为例子&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;厨师就是向 chan 写入的&lt;/li&gt;&#xA;&lt;li&gt;窗口就是缓冲队列&lt;/li&gt;&#xA;&lt;li&gt;服务员就是向 chan 读取的&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;写入数据：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;厨师准备上菜，看看窗口外有没有服务员，如果有服务员，就叫醒服务员拿菜，然后把菜给他&lt;/li&gt;&#xA;&lt;li&gt;没有服务员的话就看看窗口上菜有没有放满，如果没放满，就把菜放在窗口上，然后溜了&lt;/li&gt;&#xA;&lt;li&gt;如果窗口满了或者没有窗口，那就在窗口旁边睡觉，等待服务员把我叫醒拿菜&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;读取数据：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;先看看有没有睡觉的厨师，如果有，再看看窗口有没有菜，如果也有，那就从窗口拿走一个菜，然后叫醒厨师可以把菜放下了&lt;/li&gt;&#xA;&lt;li&gt;如果窗口放不了菜（无缓存队列） 直接叫醒厨师把他手上的菜拿过来&lt;/li&gt;&#xA;&lt;li&gt;如果没有睡觉的厨师，窗口有菜拿的话直接从窗口拿菜，拿完之后就溜了溜了&lt;/li&gt;&#xA;&lt;li&gt;如果没有睡觉的厨师窗口也没有菜，那就在窗口旁边睡觉等待厨师送菜过来&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;关闭-channel&#34;&gt;关闭 channel&#xA;&lt;/h2&gt;&lt;p&gt;关闭channel时会把&lt;code&gt;recvq&lt;/code&gt; 中的G全部唤醒，本该写入G的数据位置为nil。把 &lt;code&gt;sendq&lt;/code&gt; 中的G全部唤醒，但这些 G 会 panic。&lt;/p&gt;&#xA;&lt;p&gt;除此之外，panic出现的常见场景还有： 1. 关闭值为nil的channel 2. 关闭已经被关闭的channel 3. 向已经关闭的channel写数据&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
