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).
realization of 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.
With the followingread process in Proactor (true async)Comparison:
-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.
Practice Status
The open source C + + development Framework ACE, developed by Douglas Schmidt and others, provides a large number of platform-agnostic, support for the underlying classes of concurrency (threads, mutexes, etc.), and at a high level of abstraction, two different sets of classes--ace reactor and ACE Proactor implementations. However, although both are platform-independent, the interfaces provided vary.
ACE Proactor has a better performance on the Windows platform because Windows provides efficient asynchronous API support in the operating system (see Http://msdn2.microsoft.com/en-us/library/aa365198.aspx).
However, not all operating systems strongly support asynchrony at the system level. Like a lot of Unix systems don't do it. Therefore, on UNIX, it may be better to choose the ACE Reactor solution. However, for the best performance, developers of Web applications must maintain multiple codes for different operating systems: on Windows based on Ace Proactor, and on UNIX systems using ACE Reactor solutions.
Improvement Programme
In this section, we will try to address the challenge of building a portable framework for the Proactor and reactor models. In the improvement scenario, we move the read/write operation that was originally in the event handler to the splitter (this idea is called "reactor") to seek to convert the reactor multi-channel synchronous IO into analog asynchronous IO. As an example of reading, the improvement process is as follows:
-Registers the read-ready event and its processor, and provides the data buffer address for the splitter, which requires information such as the amount of data to read.
-Separator Wait events (such as Waiting on select ())
-Event arrival, activating separator. The splitter performs a non-blocking read operation (it has all the information needed to complete the operation) and finally calls the corresponding processor.
-the event handler handles the data of the user-defined buffer, registers the new event (and, of course, gives the data buffer address, the amount of data to be read, etc.), and finally returns the control to the splitter.
As we can see, through the transformation of the multi-channel IO mode function structure, reactor is converted into proactor mode. Before and after the transformation, the actual work done by the model did not increase, but the participants had a slight exchange of responsibilities between them. Without a change in workload, it naturally does not impair performance. A comparison of the following steps can demonstrate a constant workload:
Standard/Typical reactor:
-Step 1: Wait for the event to arrive (reactor)
-Step 2: Distribute read-ready events to user-defined processors (reactor responsible)
-Step 3: Read the data (user processor is responsible)
-Step 4: Process data (user processor is responsible)
Improved implementation of simulation Proactor:
-Step 1: Wait for the event to arrive (Proactor)
-Step 2: Get read ready event, execute read data (now by Proactor)
-Step 3: Distribute the Read completion event to the user processor (Proactor responsible)
-Step 4: Process data (user processor is responsible)
For an operating system that does not provide an asynchronous IO API, this approach hides the interface details of the socket API and exposes a complete asynchronous port. This allows us to further build fully portable, platform-independent solutions with common external interfaces.
The above scheme has been implemented by Terabit P/L Corporation (http://www.terabit.com.au/) as Tproactor. It has two versions: C + + and Java. The C + + version is developed using the ACE cross-platform underlying class, providing universal, unified, active asynchronous interfaces for all platforms.
The Boost.asio library also takes a similar approach to implementing a unified IO asynchronous interface.
<-----------
Recently, the Boost.asio class library was used in the project, which is implemented in the Proactor design pattern, see:proactor(the Boost.asio library is based on the Proactor Pattern. This design note outlines the advantages and disadvantages of this approach.), and its designing document Links: Http://asio.sourceforge.net/boost_ Asio_0_3_7/libs/asio/doc/design/index.html
First, let us examine how the Proactor design pattern was implemented in ASIO, without reference to Platform-specific Detai Ls.
Proactor design pattern (adapted from [1])
Of course, the two I/O design patterns, also in the ACE is a large number of applications, this is in the ace of related books are introduced, which in the "ACE Developer" site has a lot of good introductory articles.
such as: The Proceedings of ACE Technology-8th proactor: An object behavior pattern used to separate and dispatch processors for asynchronous event multiplexing
Proceedings of ACE Technology-7th chapter design and use of ACE Reactor (Reactor): Object-Oriented architecture for event multiplexing
Ace Programmer's Tutorial-6th reactor (Reactor): Architecture pattern for event Multiplexing and dispatch
Ace App-2nd JAWS: High-performance Web server architecture
Proactor mode in single-CPU single-core system application has unparalleled advantages, the problem now facing is: in multi-CPU multi-core system, it how to better apply the advantages of multithreading??? This is worth thinking about and practicing, perhaps creating another design pattern to suit the needs of development.
High performance I/O design patterns reactor and Proactor