在ZeroMQ(java)中,整个IO的处理流程都是分层来进行的,当然处于最下端的肯定是前面介绍过的poller以及StreamEngin了。。。。涉及到上层的话就还有session,以及socket,先用一张图来大概的描述一下整个层次关系吧。。
整个分层的结构大概就是这样吧,其中poller与StreamEngin是怎么交互的,这个就不说饿了吧,然后Session这个怎么与session之间交互呢,这个以后再说吧,其实在streamEngin里面有自己的session引用。。反正这里没啥意思。。主要就在与Session怎么与自己所属的Socket进行交互,当从最底层接收到数据之后,session如何交给上层的socket,让其来处理。。。这里就涉及到了Pipe,也就是session与自己所属的socket之间是通过pipe来进行数据传递的。。。
那么在具体的分析session与socket之前就来看看这个Pipe是怎么工作的吧,先来大概的看看它的类图:
这里可以看到Pipe继承自ZObject类型,那么可以知道Pipe可以发送,接受以及执行命令,同时也就意味着Pipe也需要由自己关联的IO线程才行,或者说有关联的mailbox。。。不过这个也不是强制的,以后再分析Socket的pipe的时候,就会发现它的pipe关联到socket自己的mailbox,但是socket的mailbox没有注册到任何的poller上面去,也就是它并没有在任何IO线程里执行,最后其实是在用户代码的线程中运行的。。。。好了。好像闲话说的比较多了。。用一张图来刻画一下Pipe是怎么运行的吧:
其实通过这张图形就已经将Pipe的运行原理基本描述出来了,pipe的两端都分别关联了两个YPipe(可以将其理解为队列)对象,例如左边将其中一个YPipe当做写端,那么在另外一边就将其看成是读端。。。
这里的YPipe对象可以将其理解为队列,至于说具体的实现,底层确实是队列,只不过是自己实现的,而且实现的还挺繁琐的,就不细说了,不过这里有向吐槽的地方,明明concurrent库中有无锁的队列ConcurrentLinkedList,在并发环境下有很好的性能,干嘛不在这个基础上进行扩展。。。。
这里另外还要看看在ZeroMQ中,也定义的有Pipe类型自己的事件回调,其定义如下:
- public interface IPipeEvents {
- void read_activated(Pipe pipe); //有数据可以读取
- void write_activated(Pipe pipe); //当前pipe有数据写
- void hiccuped(Pipe pipe); //对面的pipe替换掉了读端,也就是当前需要替换写段的时候的回调
- void terminated(Pipe pipe); //当前pipe停止的回调
- }
具体每个方法是干嘛用的注释应该说的很清楚了。。那么接下来来看看Pipe的两端是怎么进行交互的吧,首先看如何发送数据到pipe的另外一端:
- //从写端写数据局,发送给pipe的另外一端
- public boolean write (Msg msg_) {
- if (!check_write ())
- return false;
- boolean more = msg_.has_more();
- outpipe.write (msg_, more);
- if (!more)
- msgs_written++; //已经读取的msg的计数
- return true;
- }
其实这里直接就是在写端,将数据写到队列里面去就好了,那么如何通知对面当前有数据发送过来了呢,来看另外一个方法:
- //其实这里主要是给对面的pipe发送activate_read命令,表示它可以读了
- public void flush () {
- // The peer does not exist anymore at this point.
- if (state == State.terminating)
- return;
- if (outpipe != null && !outpipe.flush ()) {
- send_activate_read (peer); //向对面发送可以读取的命令
- }
- }
这个,如果看了ZObject就应该很清楚了吧,直接给命令的另外一端发送activate_read类型的命令,那么这个命令最终将会被pipe的另外一端所关联的mailbox收到,从而对面的Pipe将会在其IO线程中执行命令,对于这个命令,进行的操作是process_activate_read方法,那么来看看Pipe中这个方法的的定义吧:
- //收到命令,表示底层的pipe有数据可以读取了,这里主要是要调用事件回调,通知上层的代码,pipe有数据可以读取了
- protected void process_activate_read () {
- if (!in_active && (state == State.active || state == State.pending)) {
- in_active = true;
- sink.read_activated (this); //调用事件回调
- }
- }
这里其实就是调用当前的pipe的事件回调,来处理当前的pipe对象,其实也就是通知上层的代码,当前pipe有数据可以读了,让其进行处理。。。。
好了,那么到这里整个Pipe的运行原理就算比较的清楚了。。。
不过自己不太明白,在java中这种数据的传递明明很简单就可以实现,干嘛要搞的这么复杂。。。不过这里也有一个好处,就是将每一个对象的方法的执行都封闭在了自己的IO线程内部。。。也算是一种线程封闭原则的实现吧。。。其余的好处,好像没啥好处,而且真的觉得略繁琐。。。。
ZeroMQ(java)中组件间数据传输(Pipe的实现)的更多相关文章
-
ZeroMQ(java)中的数据流SessionBase与SocketBase
前面的文章中已经比较的清楚了ZeroMQ(java)中如何在底层处理IO, 通过StreamEngine对象来维护SelectableChannel对象以及IO的事件回调,然后通过Poller对象来维 ...
-
ZeroMQ(JAVA)中的数据流,SessionBase与SocketBase
前面的文章中已经比较的清楚了ZeroMQ(java)中如何在底层处理IO, 通过StreamEngine对象来维护SelectableChannel对象以及IO的事件回调,然后通过Poller对象来维 ...
-
Vue中组件间通信的方式
Vue中组件间通信的方式 Vue中组件间通信包括父子组件.兄弟组件.隔代组件之间通信. props $emit 这种组件通信的方式是我们运用的非常多的一种,props以单向数据流的形式可以很好的完成父 ...
-
React中组件间通信的方式
React中组件间通信的方式 React中组件间通信包括父子组件.兄弟组件.隔代组件.非嵌套组件之间通信. Props props适用于父子组件的通信,props以单向数据流的形式可以很好的完成父子组 ...
-
ZeroMQ(java)中监控Socket
基本上ZeroMQ(java)中基本的代码都算是过了一遍了吧,不过觉得它在日志这一块貌似基本没有做什么工作,也就是我们通过日志来知道ZeroMQ都发生了什么事情.. 而且由于ZeroMQ中将连接的建立 ...
-
[转] React 中组件间通信的几种方式
在使用 React 的过程中,不可避免的需要组件间进行消息传递(通信),组件间通信大体有下面几种情况: 父组件向子组件通信 子组件向父组件通信 跨级组件之间通信 非嵌套组件间通信 下面依次说下这几种通 ...
-
React 中组件间通信的几种方式
在使用 React 的过程中,不可避免的需要组件间进行消息传递(通信),组件间通信大体有下面几种情况: 父组件向子组件通信 子组件向父组件通信 非嵌套组件间通信 跨级组件之间通信 1.父组件向子组件通 ...
-
Vue中组件间传值常用的几种方式
版本说明: vue-cli:3.0 一.父子组件间传值 1.props/$emit -父组件==>>子组件: 子组件中通过定义props接收父组件中通过v-bind绑定的数据 父组件代码 ...
-
Vue学习(二)-Vue中组件间传值常用的几种方式
版本说明:vue-cli:3.0 主要分为两类: 1.父子组件间的传值 2.非父子组件间的传值 1.父子组件间传值 父组件向子组件传值 第一种方式: props 父组件嵌套的子组件中,使用v-bind ...
随机推荐
-
$.inArray()
原文链接:http://www.css88.com/jqapi-1.9/jQuery.inArray/ jQuery.inArray( value, array [, fromIndex ] )返回: ...
-
js简化判断是否为手机访问
var ua = navigator.userAgent; var ipad = ua.match(/(iPad).*OS\s([\d_]+)/), isIphone = !ipad &&am ...
-
Atitit RSA非对称加密原理与解决方案
Atitit RSA非对称加密原理与解决方案 1.1. 一.一点历史 1 1.2. 八.加密和解密 2 1.3. 二.基于RSA的消息传递机制 3 1.4. 基于rsa的授权验证机器码 4 1.5. ...
-
为IEnumerable扩展一个ForEach方法
IEnumerable没有一个ForEach方法,我们可以使用C#写一个扩展方法: Source Code: using System; using System.Collections.Generi ...
-
ANDROID版本号和版本名称的重要性介绍
当我们在刚开始学习ANDROID的时候,可能不会过多的关注这个位于manifest.xml文件中的versionCode和versionName. 但是其实一个好的版本控制,对于我们有至关重要的作用. ...
-
python学习笔记系列----(二)控制流
实际开始看这一章节的时候,觉得都不想看了,因为每种语言都会有控制流,感觉好像我不看就会了似的.快速预览的时候,发现了原来还包含了对函数定义的一些描述,重点讲了3种函数形参的定义方法,章节的最后讲述了P ...
-
c/c++面试题(2)
4.已知String类的原型是: class String { public: String(const char* str = NULL); //普通的构造函数 String(const Str ...
-
Flash Media Server 4.5 序列号 (fms4.5 激活码)
激活码一枚 ,网上找不到的..我今天放出来了哦... 1462-5864-7783-6034-8316-3718 (亲测 可用) 安装前找到系统盘下windows/system32/driv ...
-
iOS7 设置隐藏状态栏(status bar)
在info.plist 添加 UIViewControllerBasedStatusBarAppearance(View controller-based status bar appearance) ...
-
iOS_SN_深浅拷贝( 百度的)_转载
文章原地址:http://www.cnblogs.com/5ishare/p/4362459.html 深浅拷贝前提是:是实现NSCopying或者NSMutableCopying协议. 浅拷贝只是复 ...