专栏首页吴亲强的深夜食堂彻底搞懂channel原理(二)
原创

彻底搞懂channel原理(二)

图片拍摄于2021年09月25日,杭州西溪湿地。

上一篇文章彻底搞懂channel原理(一)主要介绍channel运行时是通过hchan表示的,也简单说明了hchan各个字段的含义。

我们提到,对channel的操作,本质上就是对hchan里字段的操作。因为在操作的过程中使用了互斥锁,所以保证了channel的并发安全。

这篇文章主要通过现实生活的一些例子来说明channel的一些原理,当然还是不会涉及过多源码。

无缓冲

我们都知道,channel分为无缓冲和缓冲。这两者最大的区别是什么?

我们用一个现实生活的快递例子来说明。

上面场景是快递员在等小库,当然反过来小库也可能在等快递员。

如果没有快递柜,快递员在送快递的过程中,如果家里没人,他就得在那等着,等着有人来签收快递,他才送货结束。

客户在快递员到来之前,他也不能离开家,不然快递来了没人收,所以他也得等到快递员上门,签字收了快递,他才算收货结束。

当然,客户不止有这家快递,如果快递员A在等的时候又来一个快递员B给他送货。这个快递员B不仅得等着,还得排队。等到客户到家后,肯定是先签收A的快递,然后再签收B的快递。

对应到无缓冲channel

发送数据的时候,如果没有对应的接收者ready,那么发送者就进入到等待发送队列中,等待有对应的接收者唤醒它。

接收数据的时候,如果没有对应的发送者ready,那么接收者就进入到等待接收队列中,等待有对应的发送者唤醒它。

还记得上一篇文章我们介绍过hchan的结构吗。

其中recvq表示等待接收消息的队列,sendq表示等待发送消息的队列。

我们来看waitq

本质上waitq就是一个链表,更确切的说是一个双向循环的链表。其中waitq记录了链表的头尾,sudog记录了当前等待者的上一个等待者(prev)和下一个等待者(next)。

这就好像小库在签收完A的快递后喊,下一个是谁啊?

A会说:我的下一个是B。

B会说:是我。我记得我上一个是A,目前我没有下一个,所以我是最后一个。

缓冲

看完了无缓冲队列,我们再来看缓冲队列。还是用上面的故事,

只要快递柜有空闲柜子,快递员就可以直接把快递放到柜子里,让客户自己去柜子拿。如果发送没有空闲的柜子,那就只能等,等到别人告诉我有空闲柜子,我再把快递放到空出来的柜子里。

对应到缓冲channel,上面的快递柜,就是缓冲channel中存储数据的buffer

对于发送者来说:只要缓冲区未满,发送者就可以继续发送数据存放在缓冲区。一旦缓冲区满了,发送者就只能进入到等待发送队列中,等待有对应的接收者唤醒它,然后它再把数据放入到刚刚被取走数据的位置。

对于接收者来说:只要缓冲区不为空,接收者就可以继续接收数据。一旦缓冲区空了,那么接收者就只能进入到等待接收队列中,等待有对应的发送者唤醒它。

上面还有什么问题吗?还真有。

我们取快递的时候,你一定会按照快递放入到快递柜的先后顺序取快递吗?咋么可能。

但是在channel中,是会保证消息的先进先出(FIFO)关系的。至于咋么保证的,我们终结篇解析代码细节的时候再说。

总结

这篇文章主要通过一个快递的例子来介绍channel操作的原理。下一篇我们介绍channel针对上述处理的细节逻辑。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 彻底搞懂channel原理(三)

    上一篇文章主要通过一个现实例子间接反映channel的一些原理。最后一篇开始介绍一些细节,会涉及到源码。

    吴亲库里
  • 彻底搞懂channel原理(一)

    之前断断续续看过Go几个模块的源码,可从未下笔,导致有些细节记不起来了。打算写一系列文章重新记录。

    吴亲库里
  • 彻底搞懂MyBatis插件原理及PageHelper原理

    提到插件,相信大家都知道,插件的存在主要是用来改变或者增强原有的功能,MyBatis中也一样。

    公众号 IT老哥
  • 看完让你彻底搞懂Websocket原理

    杭州前端工程师
  • 彻底搞懂NIO效率高的原理

    这篇文章读不懂的没关系,可以先收藏一下。笔者准备介绍完epoll和NIO等知识点,然后写一篇Java网络IO模型的介绍,这样可以使Java网络IO的知识体系更加...

    全菜工程师小辉
  • 手写mybatis彻底搞懂框架原理

    mybatis的前身是iBatis,其源于“Internet”和“abatis”的组合,是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。myb...

    全菜工程师小辉
  • 一文彻底搞懂 HTTPS 的工作原理!

    当你打开浏览器,访问某个网站,如果网址旁有个小锁,代表访问的网址是安全的,反之不安全。当我们没有看到那个小锁的小图标的时候,需要提高警惕,不要随意输入个人重要的...

    杰哥的IT之旅
  • 彻底搞懂彩虹表的实现原理

    7788的术语我就不多说了,简而言之,就是一种破解md5或者sha1这种哈希散列算法的一种办法。

    诺浅
  • 带你彻底搞懂-View的工作原理!

    1.ViewRoot对应ViewRootImpl类,是连接WindowManager和DecorView的纽带。View的三大流程是通过ViewRoot完成的。...

    胡飞洋
  • 彻底搞懂epoll高效运行的原理

    这篇文章读不懂的没关系,可以先收藏一下。笔者准备介绍完epoll和NIO等知识点,然后写一篇Java网络IO模型的介绍,这样可以使Java网络IO的知识体系更加...

    全菜工程师小辉
  • 彻底搞懂Object.defineProperty

    早在大半年前,掘金某位用户分享的面试题整理中有一题,简述let与const区别,你能自己模拟实现它们吗?,题目意思大概如此,时间久远我也很难找到那篇文章,当时看...

    zz_jesse
  • 彻底搞懂 Object.defineProperty

    早在大半年前,掘金某位用户分享的面试题整理中有一题,简述let与const区别,你能自己模拟实现它们吗?,题目意思大概如此,时间久远我也很难找到那篇文章,当时看...

    coder_koala
  • 彻底搞懂ArrayList

    同样是空的数组对象,和EMPTY_ELEMENTDATA区别在于,无参构造函数的空数组会用DEFAULTCAPACITY_EMPTY_ELEMENTDATA赋值...

    每天学Java
  • 彻底搞懂Scrapy的中间件(二)

    在上一篇文章中介绍了下载器中间件的一些简单应用,现在再来通过案例说说如何使用下载器中间件集成Selenium、重试和处理请求异常。

    青南
  • 彻底搞懂Java动态代理

    现在spring大行其道,经常使用的AOP功能就是动态代理机制的实现。动态代理到底是怎么回事呢?

    Criss@陈磊
  • 彻底搞懂Java动态代理

    现在spring大行其道,经常使用的AOP功能就是动态代理机制的实现。动态代理到底是怎么回事呢?

    普通程序员
  • 彻底搞懂 Git-Rebase

    来源:http://jartto.wang/2018/12/11/git-rebase/?hmsr=toutiao.io&utm_medium=toutiao....

    程序猿DD
  • 彻底搞懂HashMap(上)

    相信很多朋友对于HashMap,开发中我们几乎每天都要使用它,但是每当问到map的一些原理时,很多朋友就不知道如何去回答,甚至一问三不知,从而离我们心仪的off...

    用户8870853
  • 彻底搞懂HashMap(上)

    相信很多朋友对于HashMap,开发中我们几乎每天都要使用它,但是每当问到map的一些原理时,很多朋友就不知道如何去回答,甚至一问三不知,从而离我们心仪的off...

    用户8670130

扫码关注云+社区

领取腾讯云代金券