开发者

Does boost::asio::io_service preserve the order of handlers?

Does boost::asio::io_service guarantee that handlers are ca开发者_JS百科lled 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.


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

  • Asio 1.4.4 / Boost 1.42

    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 perform s.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.

  • Timer.5 - Synchronising handlers in multithreaded programs

  • Strands: Use Threads Without Explicit Locking

  • 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:

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜