彻底搞懂channel原理(二)

简介: 彻底搞懂channel原理(二)

上一篇文章主要介绍channel运行时是通过hchan表示的,也简单说明了hchan各个字段的含义

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

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


无缓冲


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

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


1668512242071.jpg


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


1668512257501.jpg


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

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


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

对应到无缓冲channel

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

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

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


1668512274907.jpg


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

我们来看waitq


1668512296761.jpg

1668512304580.jpg

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

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

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

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


缓冲


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


1668512323547.jpg


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

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

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


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


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


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

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


总结


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

相关文章
|
SQL 前端开发 Java
SpringMVC系列(四)之SpringMVC实现文件上传和下载
SpringMVC系列(四)之SpringMVC实现文件上传和下载
|
存储 数据挖掘 数据处理
R语言中的数据类型转换:解决常见问题的技术指南
【8月更文挑战第28天】数据类型转换是R语言编程中的一项基本技能,对于确保数据处理的准确性和效率至关重要。本文介绍了R中的基本数据类型及其转换方法,并探讨了解决常见问题的一些技巧。掌握这些知识和技巧,将有助于你更加高效地利用R语言进行数据分析和统计建模。
|
11月前
|
存储 Java
HashMap的扩容机制是怎样的
在Java中,HashMap 是一个基于哈希表的键值对集合,它以其高效的存取性能而广泛使用。HashMap 的扩容机制是其性能优化的关键部分,本文将详细介绍这一机制的工作原理和过程。
|
缓存 NoSQL 安全
玩转Redis!非常强大的Redisson分布式集合,少写60%代码
Redisson是Java的Redis客户端,提供实时数据平台服务,简化了分布式环境下的数据管理。它包含RList、RSet、RMap等分布式集合,支持ConcurrentMap和Set接口,确保线程安全和数据一致性。例如,RMap实现了本地缓存和监听器功能,允许数据监听和本地加速读取。此外,还提供了RSet的排序和去重功能,以及RQueue和RBlockingQueue等队列实现,支持阻塞操作。通过Redisson,开发者能轻松处理分布式系统的数据同步和操作。
|
12月前
|
机器学习/深度学习 人工智能 算法
量子计算算法:超越经典计算机的边界
【10月更文挑战第30天】量子计算基于量子力学原理,通过量子比特和量子门实现超越经典计算机的计算能力。本文探讨量子计算的基本原理、核心算法及其在密码学、化学、优化问题和机器学习等领域的应用前景,并讨论当前面临的挑战与未来发展方向。
|
9月前
|
存储 缓存 Serverless
使用云存储构建云上推理平台
本文介绍了大模型分布式推理的工作流、IO分析、存储需求及解决方案。通过分布式缓存和P2P能力,优化了大规模并发场景下的模型加载与分发效率,提升了推理性能。NAS文件存储和OSS加速器在高并发读取和小模型缓存中表现出色,支持秒级加载和高效数据处理。阿里云存储为开发者提供了稳定、高效的推理环境,助力AI应用快速落地。
|
11月前
|
网络协议 安全 算法
OSPFv3新特性介绍
OSPFv3新特性介绍
215 4
|
消息中间件 存储 Java
一览纵山小,原来RocketMQ是这样工作的!
本文介绍了阿里巴巴开源的高性能分布式消息队列系统RocketMQ的核心组件及其作用。RocketMQ拥有四个关键组件:NameServer、Broker、Producer和Consumer。NameServer作为注册中心维护路由信息;Broker负责消息的接收、存储和转发;Producer生成消息并通过Topic与Broker关联;Consumer则订阅并处理消息。文章详细解析了各组件的功能及交互逻辑,并展示了RocketMQ在异步通信、日志收集、流处理及事件驱动架构中的典型应用场景。通过整体框架的梳理,有助于读者更好地理解和掌握RocketMQ的工作机制。
199 4
|
传感器 负载均衡 物联网
MQTT v5共享订阅是怎么回事?如何使用共享订阅提高消息订阅的灵活性和可伸缩性?
MQTT v5共享订阅是怎么回事?如何使用共享订阅提高消息订阅的灵活性和可伸缩性?
939 1
|
数据采集 Web App开发 JavaScript
使用Puppeteer提升社交媒体数据分析的精度和效果
社交媒体是互联网上最受欢迎的平台之一,它们包含了大量的用户生成内容,如文本、图片、视频、评论等。这些内容对于分析用户行为、舆情、市场趋势等有着重要的价值。但是,如何从社交媒体上获取这些数据呢?一种常用的方法是使用网络爬虫,即一种自动化地从网页上提取数据的程序。
277 0
使用Puppeteer提升社交媒体数据分析的精度和效果