0d0a0828f2fbd005bb72bda5ce881ffd9d7bf6b5
[platform/upstream/boost.git] / libs / asio / doc / overview / async.qbk
1 [/
2  / Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
3  /
4  / Distributed under the Boost Software License, Version 1.0. (See accompanying
5  / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  /]
7
8 [section:async The Proactor Design Pattern: Concurrency Without Threads]
9
10 The Boost.Asio library offers side-by-side support for synchronous and asynchronous
11 operations. The asynchronous support is based on the Proactor design pattern
12 [link boost_asio.overview.core.async.references \[POSA2\]]. The advantages and
13 disadvantages of this approach, when compared to a synchronous-only or Reactor
14 approach, are outlined below.
15
16 [heading Proactor and Boost.Asio]
17
18 Let us examine how the Proactor design pattern is implemented in Boost.Asio,
19 without reference to platform-specific details.
20
21 [$boost_asio/proactor.png]
22
23 [*Proactor design pattern (adapted from \[POSA2\])]
24
25 [mdash] Asynchronous Operation
26
27 [:Defines an operation that is executed asynchronously, such as an asynchronous
28 read or write on a socket.]
29
30 [mdash] Asynchronous Operation Processor
31
32 [:Executes asynchronous operations and queues events on a completion event
33 queue when operations complete. From a high-level point of view, services like
34 `stream_socket_service` are asynchronous operation processors.]
35
36 [mdash] Completion Event Queue
37
38 [:Buffers completion events until they are dequeued by an asynchronous event
39 demultiplexer.]
40
41 [mdash] Completion Handler
42
43 [:Processes the result of an asynchronous operation. These are function
44 objects, often created using `boost::bind`.]
45
46 [mdash] Asynchronous Event Demultiplexer
47
48 [:Blocks waiting for events to occur on the completion event queue, and returns
49 a completed event to its caller.]
50
51 [mdash] Proactor
52
53 [:Calls the asynchronous event demultiplexer to dequeue events, and dispatches
54 the completion handler (i.e. invokes the function object) associated with the
55 event. This abstraction is represented by the `io_service` class.]
56
57 [mdash] Initiator
58
59 [:Application-specific code that starts asynchronous operations. The initiator
60 interacts with an asynchronous operation processor via a high-level interface
61 such as `basic_stream_socket`, which in turn delegates to a service like
62 `stream_socket_service`.]
63
64 [heading Implementation Using Reactor]
65
66 On many platforms, Boost.Asio implements the Proactor design pattern in terms
67 of a Reactor, such as `select`, `epoll` or `kqueue`. This implementation
68 approach corresponds to the Proactor design pattern as follows:
69
70 [mdash] Asynchronous Operation Processor
71
72 [:A reactor implemented using `select`, `epoll` or `kqueue`. When the reactor
73 indicates that the resource is ready to perform the operation, the processor
74 executes the asynchronous operation and enqueues the associated completion
75 handler on the completion event queue.]
76
77 [mdash] Completion Event Queue
78
79 [:A linked list of completion handlers (i.e. function objects).]
80
81 [mdash] Asynchronous Event Demultiplexer
82
83 [:This is implemented by waiting on an event or condition variable until a
84 completion handler is available in the completion event queue.]
85
86 [heading Implementation Using Windows Overlapped I/O]
87
88 On Windows NT, 2000 and XP, Boost.Asio takes advantage of overlapped I/O to
89 provide an efficient implementation of the Proactor design pattern. This
90 implementation approach corresponds to the Proactor design pattern as follows:
91
92 [mdash] Asynchronous Operation Processor
93
94 [:This is implemented by the operating system. Operations are initiated by
95 calling an overlapped function such as `AcceptEx`.]
96
97 [mdash] Completion Event Queue
98
99 [:This is implemented by the operating system, and is associated with an I/O
100 completion port. There is one I/O completion port for each `io_service`
101 instance.]
102
103 [mdash] Asynchronous Event Demultiplexer
104
105 [:Called by Boost.Asio to dequeue events and their associated completion
106 handlers.]
107
108 [heading Advantages] 
109
110 [mdash] Portability.
111
112 [:Many operating systems offer a native asynchronous I/O API (such as
113 overlapped I/O on __Windows__) as the preferred option for developing high
114 performance network applications. The library may be implemented in terms of
115 native asynchronous I/O. However, if native support is not available, the
116 library may also be implemented using synchronous event demultiplexors that
117 typify the Reactor pattern, such as __POSIX__ `select()`.]
118
119 [mdash] Decoupling threading from concurrency.
120
121 [:Long-duration operations are performed asynchronously by the implementation
122 on behalf of the application. Consequently applications do not need to spawn
123 many threads in order to increase concurrency.]
124
125 [mdash] Performance and scalability.
126
127 [:Implementation strategies such as thread-per-connection (which a
128 synchronous-only approach would require) can degrade system performance, due to
129 increased context switching, synchronisation and data movement among CPUs. With
130 asynchronous operations it is possible to avoid the cost of context switching
131 by minimising the number of operating system threads [mdash] typically a
132 limited resource [mdash] and only activating the logical threads of control
133 that have events to process.]
134
135 [mdash] Simplified application synchronisation.
136
137 [:Asynchronous operation completion handlers can be written as though they
138 exist in a single-threaded environment, and so application logic can be
139 developed with little or no concern for synchronisation issues.]
140
141 [mdash] Function composition.
142
143 [:Function composition refers to the implementation of functions to provide a
144 higher-level operation, such as sending a message in a particular format. Each
145 function is implemented in terms of multiple calls to lower-level read or write
146 operations.]
147
148 [:For example, consider a protocol where each message consists of a
149 fixed-length header followed by a variable length body, where the length of the
150 body is specified in the header. A hypothetical read_message operation could be
151 implemented using two lower-level reads, the first to receive the header and,
152 once the length is known, the second to receive the body.]
153
154 [:To compose functions in an asynchronous model, asynchronous operations can be
155 chained together. That is, a completion handler for one operation can initiate
156 the next. Starting the first call in the chain can be encapsulated so that the
157 caller need not be aware that the higher-level operation is implemented as a
158 chain of asynchronous operations.]
159
160 [:The ability to compose new operations in this way simplifies the development
161 of higher levels of abstraction above a networking library, such as functions
162 to support a specific protocol.]
163
164 [heading Disadvantages] 
165
166 [mdash] Program complexity.
167
168 [:It is more difficult to develop applications using asynchronous mechanisms
169 due to the separation in time and space between operation initiation and
170 completion. Applications may also be harder to debug due to the inverted flow
171 of control.]
172
173 [mdash] Memory usage.
174
175 [:Buffer space must be committed for the duration of a read or write operation,
176 which may continue indefinitely, and a separate buffer is required for each
177 concurrent operation. The Reactor pattern, on the other hand, does not require
178 buffer space until a socket is ready for reading or writing.]
179
180 [heading References]
181
182 \[POSA2\] D. Schmidt et al, ['Pattern Oriented Software Architecture, Volume
183 2]. Wiley, 2000.
184
185 [endsect]