This article summarizes the description of these two models on the Internet resources
Original address: http://www.cnblogs.com/dawen/archive/2011/05/18/2050358.html
1. Standard definition
Two I/O multiplexing modes: Reactor and Proactor
Generally, the I/O multiplexing mechanism relies on an event demultiplexer. The Separator object separates the I/O events from the event source and distributes them to the corresponding Read/write event handler (the event Handler). The developer pre-registers the events and their event handlers (or callback functions) that need to be processed, and the event separator is responsible for passing the request events to the event handler. The two patterns associated with event separators are reactor and proactor. The reactor mode uses synchronous IO, while the proactor uses asynchronous IO.
In reactor, the event splitter is responsible for waiting for the file descriptor or socket to be ready for read and write operations, then passing the ready event to the corresponding processor, and finally the processor is responsible for completing the actual read and write work.
In Proactor mode, the processor--or the event splitter that is the processor--is only responsible for initiating asynchronous read and write operations. The IO operation itself is done by the operating system. The parameters passed to the operating system need to include the user-defined data buffer address and data size, from which the operating system can get the data it needs to write the operation, or write the data read from the socket. The event splitter captures the IO operation completion event and then passes the event to the corresponding processor. For example, on Windows, the processor initiates an asynchronous IO operation, and the event splitter waits for the IoCompletion event. Typical asynchronous Pattern implementations are built on the operating system's support for asynchronous APIs, which we call "system-level" asynchronous or "true" asynchrony because the application relies entirely on the operating system to perform real IO work.
For example, it will help to understand the difference between reactor and Proactor, as in the case of a read operation (similar to a class operation).
Implement read in reactor:
-Register read-ready events and corresponding event handlers
-Event Splitter Wait event
-the event arrives, activates the splitter, and the splitter invokes the event corresponding to the processor.
-the event handler completes the actual read operation, processes the read data, registers the new event, and then returns control.
Implement read in Proactor:
-the processor initiates an asynchronous read operation (note: The operating system must support asynchronous IO). In this case, the processor ignores the IO-ready event, and it focuses on the completion event.
-Event splitter waits for Operation completion event
-During the separator wait, the operating system takes advantage of the parallel kernel thread to perform the actual read operation and stores the resulting data in the user-defined buffer, and finally notifies the event splitter that the read operation is complete.
-The event splitter calls the processor.
-the event handler handles the data in the user-defined buffer, then initiates a new asynchronous operation and returns control to the event splitter.
As you can see, the same point in the two patterns is the event notification for an IO event (that is, telling a module that the IO operation can or has been completed). Structurally, the two also have the same point: Demultiplexor is responsible for committing the IO operation (async), querying whether the device is operational (synchronous), and then callback handler when the condition is met; the difference is that, in the case of async (Proactor), when the callback handler, Indicates that the IO operation is complete; In the case of synchronization (Reactor), the callback handler indicates that the IO device can perform an operation (can read or can write).
2. Popular Understanding
The use of the Proactor framework and the reactor framework can greatly simplify the development of Web applications, but their focus is different.
The user-defined action in the reactor framework is called before the actual operation. For example, if you define the operation to write data to a socket, then when the socket can receive the data, your operation will be called, and the user-defined action in the Proactor framework is called after the actual operation. For example, if you define an operation to display the data that is read from the socket, your operation will be called when the read operation is completed.
Both Proactor and reactor are design patterns in concurrent programming. In my opinion, they are all used to distribute/detach IO operation events. The so-called IO event is an IO operation such as Read/write. "Distribute/detach" is the notification of a separate IO event to the upper module. The two modes differ in that Proactor is used for asynchronous IO, while reactor is used to synchronize IO.
3. Remarks
In fact, these two patterns in ACE (Network Library) are reflected in, if you want to understand the two modes, you can refer to the ACE source code, ACE is open Source Network framework, it is worth learning.
Original address: http://daimojingdeyu.iteye.com/blog/828696
Reactor this word translated into Chinese there is really no suitable, many places called reactor mode, but more like the direct call reactor mode, in fact, I think that the respondent model better understand some. By understanding that this pattern is more like a bodyguard, has been waiting for your call, or call the Beast.
Concurrent systems often use reactor mode, instead of common multithreading, saving system resources and improving the throughput of the system.
A more intuitive way to introduce the advantages of this way, by comparing with the usual multi-threaded way, may be better understood.
Take a food and beverage as an example, each person to eat is an event, he will first look at the menu, then order food. Just like a website will have a lot of requests, ask the server to do something. We need our service staff to deal with these dining events.
The way in which multithreading is handled is this:
A person comes to dinner, a waiter goes to the service, then the guest will look at the menu and order. The waiter will give the menu to the back chef.
Two people to eat, two waiter to service ...
Five people to eat, five waiter to service ...
This is the multithreading approach, an event arrives, there will be a thread service. Obviously this way in the case of less people will have a very good user experience, each guest feel that they are VIP, dedicated service. If the restaurant has been in this way for up to 5 guests at the same time, this restaurant can be very well served.
A good news came, because the service of this shop is good, the people who eat more up. At the same time will come 10 guests, the boss is very happy, but only 5 waiter, so you can not one-to-man service, some guests will not be tube. The boss also invited 5 waiter, now good, and can everyone by VIP treatment.
More and more people are satisfied with this restaurant, the source is more, at the same time to eat people to 20 people, the boss is not happy, and then please waiter, occupy the place do not say, also to open wages, and then people will save money. What do we do? The boss thought, 10 waiter to deal with 20 guests is also able to deal with, waiter diligent point is good, wait for a guest to wait for another, or time. Considering the overall consideration, the boss decided to use a thread pool of 10 service staff ~ ~ ~
But there is a serious drawback is that if you are receiving waiter service, the order is slow, other guests may have to wait for a long time. Some hot-tempered guests may not be able to wait to leave.
Reactor how to deal with this problem:
The boss later found that the guests order relatively slow, the big waiter is waiting for the guests to order, its hard work is not too much. Boss can be the boss of course a bit different place, finally found a new method, that is: when the guests order, the waiter can go to greet other guests, and so the guests ordered a good dish, directly greeted a "waiter", immediately there is a waiter past service. Hey, and then after the boss has this new method, he made a layoff, leaving only a waiter! This is the use of a single thread to do multi-threaded things.
The actual restaurant is used in the reactor mode in the service. Some of the design models are actually from life.
The reactor mode is mainly to improve the throughput of the system and handle more things under limited resources.
On a single-core machine, multithreading does not improve the performance of the system unless there are some blocking situations. Otherwise, the overhead of thread switching slows down processing. Just like you do two things alone, 1, cut an apple. 2, cut a watermelon. Then you can do one thing, I think you will do one thing. If you use multi-threading at this time, cut the apples for a while, and slice the watermelon, you can be similar to which speed is fast. This means that it may be slower to process multithreading on a single-core machine.
But when there are obstacles to the operation, the advantages of multithreading will show up, now you have two other things to do, 1, cutting an apple. 2. Burn a pot of boiling water. I don't think anyone's going to do another thing, and you're going to have to boil the water and cut the apples.
The theory of things will not be said, please refer to the annex "Reactor-siemens.pdf". More pictures, e-text is not good can also be read.
: http://files.cnblogs.com/files/lfsblack/reactor.pdf
Original address: http://xmuzyq.iteye.com/blog/783218
In the high-performance I/O design, there are two well-known modes reactor and Proactor modes, where reactor mode is used for synchronous I/O, and Proactor is used for asynchronous I/O operations.
Before comparing these two patterns, we first understand a few concepts, what is blocking and non-blocking, what is synchronous and asynchronous, synchronous and asynchronous are for application and kernel interaction, synchronous refers to the user process trigger IO operation and wait or poll to see if IO operation is ready, Asynchronous means that the user process triggers an IO operation and then starts to do its own thing, and when the IO operation is complete, I get the IO completion notification. While blocking and non-blocking is for the process at the time of access to data, according to the readiness of the IO operation to take a different way, white is a read or write operation function implementation, blocking mode read or write function will wait, and not blocking mode, read or write function immediately return a status value.
Generally speaking I/O models can be divided into: synchronous blocking, synchronous non-blocking, asynchronous blocking, asynchronous non-blocking IO
Synchronous Blocking IO:
In this way, the user process must wait for the IO operation to complete after initiating an IO operation, and the user process will not run until the IO operation is actually completed. Java's traditional IO model belongs to this way!
Synchronous non-blocking IO:
In this way, the user process initiates an IO operation to return to doing something else, but the user process needs to ask the IO operation to be ready from time to time, which requires the user process to keep asking, thus introducing unnecessary waste of CPU resources. The current Java NiO belongs to synchronous non-blocking IO.
Asynchronous blocking IO:
In this way, after the application initiates an IO operation, does not wait for the kernel IO operation to complete, and so on after the kernel completes the IO operation notifies the application, this is actually the synchronization and the asynchronous most crucial difference, the synchronization must wait or the initiative to ask whether the IO completes, then why say is blocked? Because this is done by a select system call, and the Select function itself is implemented in a blocking way, the advantage of using the Select function is that it can listen to multiple file handles at the same time, thus improving the concurrency of the system!
Asynchronous non-blocking IO:
In this mode, the user process only needs to initiate an IO operation and then return immediately, after the actual completion of the IO operation, the application will get the IO operation to complete the notification, at this time the user process only need to process the data, do not need to do the actual IO read and write operations, Because the actual IO read or write operation has been completed by the kernel. There is currently no support for this IO model in Java.
After figuring out the above concepts, we look back at the reactor mode and the Proactor mode.
First look at the reactor mode, the reactor mode applied to the synchronous I/O scenario. Let's take a read operation and write operation as an example to see the specific steps in reactor:
Read operation:
1. Application registration Read on-demand event and associated event handler
2. Event separators wait for events to occur
3. Event Splitter invokes the event handler registered in the first step when a read-as-needed event occurs
4. The event handler performs the actual read operation first and then further processes the read-based content
A write operation is similar to a read operation, except that the first step is to register a write-ready event.
Let's take a look at the process of read and write operations in Proactor mode:
Read operation:
1. The application initializes an asynchronous read operation and then registers the appropriate event handler, at which point the event handler does not focus on the read-ready event, but instead focuses on the read completion event, which is the key to distinguish it from the reactor.
2. Event Splitter waits for read operation completion event
3. When the event splitter waits for the read operation to complete, the operating system invokes the kernel thread to complete the read operation and puts the contents of the read into the buffer passed by the user. This is also a bit different from reactor, where the application needs to pass the buffer proactor.
4. After the event splitter captures the read completion event, activates the event handler registered by the application, and the event handler reads the data directly from the buffer without the need for actual read operations.
Write operations and read operations in Proactor, except that events of interest are write completion events.
As can be seen from the above, the main difference between the reactor and Proactor modes is that the real read and write operations are done by someone, and the reactor requires the application to read or write the data itself, whereas in Proactor mode, the application does not need to perform the actual read/write process. It only needs to read or write from the buffer, and the operating system reads the buffer or writes the buffer to the real IO device.
To sum up, synchronous and asynchronous is relative to the application and the core of the interaction, synchronization needs to proactively ask, and asynchronous when the kernel at the time of the Io event to notify the application, and blocking and non-blocking is only the system calls the system when the function of the implementation of the way.
Also attached is a summary link: http://blog.csdn.net/caiwenfeng_for_23/article/details/8458299
The following is a good summary: http://www.cnblogs.com/daoluanxiaozi/p/3274925.html
Here are a few more articles:
Http://www.cnblogs.com/pigerhan/p/3474217.html
Http://www.2cto.com/kf/201504/395318.html
http://blog.jobbole.com/59676/
http://cshbbrain.iteye.com/blog/1706269
Http://www.cppblog.com/kevinlynx/archive/2008/06/06/52356.html
Reactor mode and Proactor mode