Does boost::asio::io_service
guarantee that handlers are called in the same order that they are given via post()
? I can't find anything saying this in the documentation. Assume that calls to io_service::post
are serialized.
The current implementation does execute things in the sequence you post them, but ordering is only guaranteed for handlers that are explicitly post()ed through a strand
.
afaik if you want guaranteed ordering of post
handler execution you have to use strand
as described in the docs.
The current implementation does execute things in the sequence you post them, but ordering is only guaranteed for handlers that are explicitly post()ed through a strand
.
~~It seemed for ~~strand
not to preserve handler execution by the order that you post
(unlike LinkedHashMap, when you iterate, you iterate the elements by the order that you've inserted them). I think it just ensures those handlers won't be invoked at the same time.
See also How strands guarantee correct execution of pending events in boost.asio
strand provides a guarantee for non-concurrency and the invocation order of handlers
In some case, there is no guarantee correct execution if using io_context::strand::wrap (deprecated) or bind_executor in async_op_1(..., s.wrap(a));
. When the async operation completes, the wrapped handler will call s.dispatch(a)
, but the completion time is uncertain.
The
io_context::strand
class provides the ability to post and dispatch handlers with the guarantee that none of those handlers will execute concurrently.
See also
-
Documented the guarantee made by strand objects with respect to order of handler invocation.
io_context::strand - Order of handler invocation
Note that in the following case:
async_op_1(..., s.wrap(a)); async_op_2(..., s.wrap(b));
the completion of the first async operation will perform
s.dispatch(a)
, and the second will performs.dispatch(b)
, but the order in which those are performed is unspecified. That is, you cannot state whether one happens-before the other. Therefore none of the above conditions are met and no ordering guarantee is made.c++ - boost::io_service How to guarantee handler execution sequence
strand
provides both the guarantee of not executing completion handlers concurrently and defines the order of handler invocation. In short, completion handlers posted into a strand
are executed in the same order in which they are posted.
Therefore:
strand_.post(&task1);
strand_.post(&task2);
strand_.post(&task3);
Guarantees order of handler invocation is task1
-> task2
-> task3
. However, wrapped completion handlers for asynchronous operations are not guaranteed, as the order in which asynchronous operations are performed is unspecified. For example, the following does not provide the same guarantee:
async_read(socket1, ..., strand_.wrap(&task1));
async_read(socket2, ..., strand_.wrap(&task2));
async_read(socket3, ..., strand_.wrap(&task3));
If completion handlers must be invoked in a specified order for asynchronous operations, then either:
Queue completion handlers and manage the order manually.
Serialize all asynchronous operations. For example, async_op_1
's completion handler task1
initiates async_op_2
with a completion handler of task2
.
Here is the relevant excerpt from io_service::strand
's order of handler invocation documentation:
© 2022 - 2024 — McMap. All rights reserved.