async.qbk
来自「Boost provides free peer-reviewed portab」· QBK 代码 · 共 186 行
QBK
186 行
[/ / Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) / / Distributed under the Boost Software License, Version 1.0. (See accompanying / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) /][section:async The Proactor Design Pattern: Concurrency Without Threads]The Boost.Asio library offers side-by-side support for synchronous and asynchronousoperations. The asynchronous support is based on the Proactor design pattern[link boost_asio.overview.core.async.references \[POSA2\]]. The advantages anddisadvantages of this approach, when compared to a synchronous-only or Reactorapproach, are outlined below.[heading Proactor and Boost.Asio]Let us examine how the Proactor design pattern is implemented in Boost.Asio,without reference to platform-specific details.[$boost_asio/proactor.png][*Proactor design pattern (adapted from \[POSA2\])][mdash] Asynchronous Operation[:Defines an operation that is executed asynchronously, such as an asynchronousread or write on a socket.][mdash] Asynchronous Operation Processor[:Executes asynchronous operations and queues events on a completion eventqueue when operations complete. From a high-level point of view, services like`stream_socket_service` are asynchronous operation processors.][mdash] Completion Event Queue[:Buffers completion events until they are dequeued by an asynchronous eventdemultiplexer.][mdash] Completion Handler[:Processes the result of an asynchronous operation. These are functionobjects, often created using `boost::bind`.][mdash] Asynchronous Event Demultiplexer[:Blocks waiting for events to occur on the completion event queue, and returnsa completed event to its caller.][mdash] Proactor[:Calls the asynchronous event demultiplexer to dequeue events, and dispatchesthe completion handler (i.e. invokes the function object) associated with theevent. This abstraction is represented by the `io_service` class.][mdash] Initiator[:Application-specific code that starts asynchronous operations. The initiatorinteracts with an asynchronous operation processor via a high-level interfacesuch as `basic_stream_socket`, which in turn delegates to a service like`stream_socket_service`.][heading Implementation Using Reactor]On many platforms, Boost.Asio implements the Proactor design pattern in termsof a Reactor, such as `select`, `epoll` or `kqueue`. This implementationapproach corresponds to the Proactor design pattern as follows:[mdash] Asynchronous Operation Processor[:A reactor implemented using `select`, `epoll` or `kqueue`. When the reactorindicates that the resource is ready to perform the operation, the processorexecutes the asynchronous operation and enqueues the associated completionhandler on the completion event queue.][mdash] Completion Event Queue[:A linked list of completion handlers (i.e. function objects).][mdash] Asynchronous Event Demultiplexer[:This is implemented by waiting on an event or condition variable until acompletion handler is available in the completion event queue.][heading Implementation Using Windows Overlapped I/O]On Windows NT, 2000 and XP, Boost.Asio takes advantage of overlapped I/O toprovide an efficient implementation of the Proactor design pattern. Thisimplementation approach corresponds to the Proactor design pattern as follows:[mdash] Asynchronous Operation Processor[:This is implemented by the operating system. Operations are initiated bycalling an overlapped function such as `AcceptEx`.][mdash] Completion Event Queue[:This is implemented by the operating system, and is associated with an I/Ocompletion port. There is one I/O completion port for each `io_service`instance.][mdash] Asynchronous Event Demultiplexer[:Called by Boost.Asio to dequeue events and their associated completionhandlers.][heading Advantages] [mdash] Portability.[:Many operating systems offer a native asynchronous I/O API (such asoverlapped I/O on __Windows__) as the preferred option for developing highperformance network applications. The library may be implemented in terms ofnative asynchronous I/O. However, if native support is not available, thelibrary may also be implemented using synchronous event demultiplexors thattypify the Reactor pattern, such as __POSIX__ `select()`.][mdash] Decoupling threading from concurrency.[:Long-duration operations are performed asynchronously by the implementationon behalf of the application. Consequently applications do not need to spawnmany threads in order to increase concurrency.][mdash] Performance and scalability.[:Implementation strategies such as thread-per-connection (which asynchronous-only approach would require) can degrade system performance, due toincreased context switching, synchronisation and data movement among CPUs. Withasynchronous operations it is possible to avoid the cost of context switchingby minimising the number of operating system threads [mdash] typically alimited resource [mdash] and only activating the logical threads of controlthat have events to process.][mdash] Simplified application synchronisation.[:Asynchronous operation completion handlers can be written as though theyexist in a single-threaded environment, and so application logic can bedeveloped with little or no concern for synchronisation issues.][mdash] Function composition.[:Function composition refers to the implementation of functions to provide ahigher-level operation, such as sending a message in a particular format. Eachfunction is implemented in terms of multiple calls to lower-level read or writeoperations.][:For example, consider a protocol where each message consists of afixed-length header followed by a variable length body, where the length of thebody is specified in the header. A hypothetical read_message operation could beimplemented using two lower-level reads, the first to receive the header and,once the length is known, the second to receive the body.][:To compose functions in an asynchronous model, asynchronous operations can bechained together. That is, a completion handler for one operation can initiatethe next. Starting the first call in the chain can be encapsulated so that thecaller need not be aware that the higher-level operation is implemented as achain of asynchronous operations.][:The ability to compose new operations in this way simplifies the developmentof higher levels of abstraction above a networking library, such as functionsto support a specific protocol.][heading Disadvantages] [mdash] Program complexity.[:It is more difficult to develop applications using asynchronous mechanismsdue to the separation in time and space between operation initiation andcompletion. Applications may also be harder to debug due to the inverted flowof control.][mdash] Memory usage.[:Buffer space must be committed for the duration of a read or write operation,which may continue indefinitely, and a separate buffer is required for eachconcurrent operation. The Reactor pattern, on the other hand, does not requirebuffer space until a socket is ready for reading or writing.][heading References]\[POSA2\] D. Schmidt et al, ['Pattern Oriented Software Architecture, Volume2]. Wiley, 2000.[endsect]
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?