【问题标题】:Does boost::asio::io_service preserve the order of handlers?boost::asio::io_service 是否保留处理程序的顺序?
【发布时间】:2011-09-20 12:45:49
【问题描述】:

boost::asio::io_service 是否保证处理程序的调用顺序与通过post() 给出的顺序相同?我在文档中找不到任何这样的说法。假设对io_service::post 的调用是序列化的。

【问题讨论】:

  • 如果您使用的是 Boost.Asio,那您肯定是太谦虚了,因为这是解决难题的明智方法。

标签: c++ multithreading boost asynchronous boost-asio


【解决方案1】:

如果你想保证post处理程序执行的顺序,你必须使用strandas described in the docs

【讨论】:

  • 如果只有 1 个工作线程,并且需要排序,我们是否还需要一个链,或者当有 1 个工作线程时不需要链?
【解决方案2】:

当前的实现确实按照您发布它们的顺序执行事物,但只有通过strand 显式发布()的处理程序才能保证排序。

【讨论】:

  • 如果只有 1 个工作线程,并且需要排序,我们是否还需要一个链,或者当有 1 个工作线程时不需要链?
【解决方案3】:

~~strand 似乎不会按照您 post 的顺序保留处理程序的执行(与 LinkedHashMap 不同,当您迭代时,您按照插入元素的顺序迭代元素)。我认为它只是确保不会同时调用这些处理程序。~~

另见How strands guarantee correct execution of pending events in boost.asio

strand为非并发和handlers的调用顺序提供了保证

在某些情况下,如果在async_op_1(..., s.wrap(a)); 中使用io_context::strand::wrap(已弃用)或bind_executor,则无法保证正确执行。当异步操作完成后,封装的handler会调用s.dispatch(a),但完成时间不确定。

io_context::strand 类提供了发布和分派处理程序的能力,并保证这些处理程序都不会同时执行。

另见

strand 提供不同时执行完成处理程序的保证并定义处理程序调用的顺序。简而言之,发布到 strand 的完成处理程序按照发布的顺序执行。

因此:

strand_.post(&task1);
strand_.post(&task2);
strand_.post(&task3);

保证处理程序调用的顺序是task1 -> task2 -> task3。但是,不能保证异步操作的包装完成处理程序,因为执行异步操作的顺序是未指定的。例如,以下不提供相同的保证:

async_read(socket1, ..., strand_.wrap(&task1));
async_read(socket2, ..., strand_.wrap(&task2));
async_read(socket3, ..., strand_.wrap(&task3));

如果必须按指定顺序调用完成处理程序以进行异步操作,则:

队列完成处理程序并手动管理订单。 序列化所有异步操作。例如,async_op_1 的完成处理程序 task1 使用完成处理程序 task2 启动 async_op_2

以下是io_service::strand的处理程序调用顺序文档的相关摘录:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 2017-09-17
    • 2014-04-21
    • 2011-12-18
    相关资源
    最近更新 更多