In Zeromq (Java), the entire IO processing process is layered to carry out, of course, at the bottom of the list is certainly the previous introduction of Poller and Streamengin .... When it comes to the top, there is the session, and the socket, first with a picture to describe the whole hierarchy of the relationship it.
The structure of the entire hierarchy is probably so, where Poller and Streamengin is how to interact, this does not say hungry, and then the session this how to interact with the session, this later on, In fact, in the Streamengin has its own session reference. It doesn't mean anything here anyway. Mainly in and how the session with their own socket to interact with, when received from the bottom of the data, the session how to give the upper socket, let it handle ... This involves the pipe, that is, the session and its own socket between the data transfer through the pipe ...
So before the specific analysis of the session and the socket to see how this pipe works, first of all to look at its class diagram:
Here you can see that the pipe inherits from the Zobject type, so you know that the pipe can be sent, accepted, and executed, and it also means that the pipe needs to be connected by its own IO thread, or that it has an associated mailbox ... But this is not mandatory, later analysis of the socket pipe, you will find its pipe associated to the socket's own mailbox, but the socket mailbox not registered to any of the poller above go, That is, it is not executed in any IO thread, and it is actually running in the thread of the user code .... All right. It seems that gossip is much more. Use a picture to describe how the pipe works:
In fact, through this figure has been the operation of the pipe is basically described, the two ends of the pipe are associated with two ypipe (can be interpreted as a queue) object, such as the left side of one of the ypipe as the writing end, then on the other side of it as a read end ...
Here the Ypipe object can be understood as a queue, as to say the specific implementation, the bottom is really a queue, but it is self-realization, and the implementation of a very cumbersome, not detailed, but here there is a place to spit groove, Clearly concurrent in the library there is no lock queue concurrentlinkedlist, in the concurrency environment has a good performance, why do not expand on this basis ....
Here is another look at the ZEROMQ, also defined by the pipe type of its own event callback, which is defined as follows:
[Java]View Plaincopy
- Public interface Ipipeevents {
- void read_activated (pipe pipe); There is data to read
- void write_activated (pipe pipe); Current pipe has data to write
- void hiccuped (pipe pipe); The opposite pipe replaces the read end, which is the callback that currently needs to replace the write segment.
- void terminated (pipe pipe); Callback for current pipe stop
- }
Each of the specific methods is why the comments should be very clear. So let's see how the ends of the pipe interact with each other, and first look at how to send the data to the other end of the pipe:
[Java]View Plaincopy
- Write the data from the writing end and send it to the other end of the pipe.
- Public Boolean write (Msg msg_) {
- if (!check_write ())
- return false;
- Boolean more = Msg_.has_more ();
- Outpipe.write (Msg_, more);
- if (!more)
- msgs_written++; The count of the MSG that has been read
- return true;
- }
In fact, this is directly in the writing end, the data written to the queue inside, then how to notify the opposite of the current data sent over it, to see another method:
[Java]View Plaincopy
- In fact here is mainly to the opposite pipe to send Activate_read command, indicating that it can read the
- public void Flush () {
- The peer does not exist anymore on this point.
- if (state = = state.terminating)
- Return
- if (outpipe! = null &&!outpipe.flush ()) {
- Send_activate_read (peer); Send commands that can be read to the opposite side
- }
- }
This, if you see the zobject should be very clear, directly to the other side of the command to send activate_read type of command, then the command will eventually be the other end of the pipe is associated with the mailbox received, so that the opposite pipe will be executed in its IO thread command , for this command, the operation is the Process_activate_read method, then take a look at the definition of this method in the pipe:
[Java]View Plaincopy
- Received the command, indicating that the bottom pipe has data can be read, here is mainly to invoke the event callback, notify the upper layer of code, pipe has data can read the
- protected void Process_activate_read () {
- if (!in_active && (state = = State.active | | state = = state.pending)) {
- In_active = true;
- Sink.read_activated (this); Invoke Event Callback
- }
- }
Here is actually called the current pipe of the event callback to deal with the current pipe object, in fact, is the notification of the upper layer of code, the current pipe has data can be read, let it be processed ....
Well, then here the whole pipe operation principle even more clear ...
But I do not understand, in Java this data transfer is very simple can be achieved, why to make so complex ... However, there is also a benefit, that is, the execution of the methods of each object is enclosed within its own IO thread ... is also a thread closure principle of the implementation of it ... The rest of the benefits, like nothing good, and really feel a little cumbersome ....
Data transfer between components in ZeroMQ (Java) (Implementation of pipe)