彻底搞懂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针对上述处理的细节逻辑

相关文章
|
6月前
解释一下ConditionVariable的工作原理。
解释一下ConditionVariable的工作原理。
90 6
|
6月前
muduo源码剖析之channel通道类
channel是muduo中的事件分发器,它只属于一个EventLoop,Channel类中保存着IO事件的类型以及对应的回调函数,每个channel只负责一个文件描述符,但它并不拥有这个文件描述符。channel是在epoll和TcpConnection之间起沟通作用,故也叫做通道,其它类通过调用channel的setCallbcak来和建立channel沟通关系。
102 0
|
18天前
|
Java Linux 应用服务中间件
【编程进阶知识】高并发场景下Bio与Nio的比较及原理示意图
本文介绍了在Linux系统上使用Tomcat部署Java应用程序时,BIO(阻塞I/O)和NIO(非阻塞I/O)在网络编程中的实现和性能差异。BIO采用传统的线程模型,每个连接请求都会创建一个新线程进行处理,导致在高并发场景下存在严重的性能瓶颈,如阻塞等待和线程创建开销大等问题。而NIO则通过事件驱动机制,利用事件注册、事件轮询器和事件通知,实现了更高效的连接管理和数据传输,避免了阻塞和多级数据复制,显著提升了系统的并发处理能力。
34 0
|
6月前
|
Go
Go语言Channel进阶:巧妙运用超时机制
Go语言Channel进阶:巧妙运用超时机制
332 0
|
6月前
|
监控 网络协议 调度
Netty Review - 深入探讨Netty的心跳检测机制:原理、实战、IdleStateHandler源码分析
Netty Review - 深入探讨Netty的心跳检测机制:原理、实战、IdleStateHandler源码分析
377 0
|
缓存 移动开发 网络协议
TCP编写服务器,客户端以及遇到的两个问题,Socket,ServerScket 类,flush(),方法。以及多线程解决,及改进的线程池写法,IO多路复用的思想,C10K,C10M的阐述。万字超细
TCP编写服务器,客户端以及遇到的两个问题,Socket,ServerScket 类,flush(),方法。以及多线程解决,及改进的线程池写法,IO多路复用的思想,C10K,C10M的阐述。万字超细
|
程序员
难倒了80%程序员的题,谈谈你对Netty中,Pipeline工作原理的理解
1位工作8年的小伙伴,去某东面试IM部门,被问到这样一道面试题。说,请你谈一谈你对Netty Pipeline设计原理的理解。当时,他说只是用过Netty的Pipline,原理没有深入了解过,然后就没有然后了。
80 0
|
存储 缓存 Java
golang channel的创建、接受和发送原理讲透
golang channel的创建、接受和发送原理讲透
|
Java Linux Windows
通俗易懂的JAVA BIO NIO AIO 原理白话文解释,区别,优缺点及代码使用案例
通俗易懂的JAVA BIO NIO AIO 原理白话文解释,区别,优缺点及代码使用案例
通俗易懂的JAVA BIO NIO AIO 原理白话文解释,区别,优缺点及代码使用案例
|
Web App开发 移动开发 前端开发
看完让你彻底搞懂Websocket原理
看完让你彻底搞懂Websocket原理
328 0
看完让你彻底搞懂Websocket原理