什么时候已取消的boost :: ASIO处理程序处理程序去跑? [英] When do handlers for cancelled boost::asio handlers get to run?

查看:138
本文介绍了什么时候已取消的boost :: ASIO处理程序处理程序去跑?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

升压文档<一个href=\"http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio/reference/basic_stream_socket/cancel/overload1.html\"相对=nofollow>说是取消了异步连接,即时发送和接收的完成,并取消了操作处理程序将被传递了boost :: ASIO ::错误:: operation_aborted错误。

The boost docs say that cancelled async connect, send and receive finish immediately, and the handlers for cancelled operations will be passed the boost::asio::error::operation_aborted error.

我想找出是否取消处理程序获取运行(并看到operation_aborted错误)其他(非取消,而新计划)完成处理程序运行。

I would like to find out if the cancelled handler gets to run (and see the operation_aborted error) before other (non-cancelled, and newly scheduled) completion handlers run.

下面是我所关心的时间表:

Here is the timeline that concerns me:

acceptHandler和readHandler在同一事件循环和相同的线程中运行。

acceptHandler and readHandler are running on the same event loop and the same thread.


  • t0时刻 - readHandler上oldConnectionSocket运行
  • 时间t1 - acceptHandler运行
  • 时间t2 - acceptHandler调用oldConnectionSocket.cancel
  • 时间t3 - acceptHandler关闭oldConnectionSocket
  • 时间t4 - acceptHandler调用newConnectionSocket.async_read(... ... readHandler)
  • 时间t5 - readHandler被称为(从哪些方面?)
  • time t0 - readHandler is running on oldConnectionSocket
  • time t1 - acceptHandler runs
  • time t2 - acceptHandler calls oldConnectionSocket.cancel
  • time t3 - acceptHandler closes oldConnectionSocket
  • time t4 - acceptHandler calls newConnectionSocket.async_read(...readHandler...)
  • time t5 - readHandler is called (from which context?)

在t5是否有可能readHandler在newConnectionSocket上下文中调用的它被称为与在oldConnectionSocket背景下operation_aborted错误?

Is it possible at t5 for readHandler to be called in the newConnectionSocket context before it is called with the operation_aborted error in the oldConnectionSocket context?

推荐答案

取消操作将立即发布它们的处理程序延期调用。但是, io_service对象 使得处理程序的调用顺序上没有保证。因此, io_service对象可以选择调用ReadHandlers以任何顺序。目前,只有 保证订货在一定条件下,指定

Cancelled operations will immediately post their handlers for deferred invocation. However, the io_service makes no guarantees on the invocation order of handlers. Thus, the io_service could choose to invoke the ReadHandlers in either order. Currently, only a strand specifies guaranteed ordering under certain conditions.

在一个完成处理程序,如果目标是要知道哪些I / O对象是与操作相关的,则考虑构建完成处理程序,以便它具有一个明确的手柄到I / O对象。这是使用以下任一常完成:

Within a completion handler, if the goal is to know which I/O object was associated with the operation, then consider constructing the completion handler so that it has an explicit handle to the I/O object. This is often accomplished using any of the following:


  • 自定义函子

  • 的std :: bind()的的boost :: bind()的

  • 一个C ++ 11的lambda

一个常见的​​成语是让I / O对象由从的 的boost :: enable_shared_from_this&LT;&GT; 。当一个类从的boost :: enable_shared_from_this 继承,它提供了一个 shared_from_this()返回一个有效的<$ 成员函数C $ C>的shared_ptr 实例这个。在的shared_ptr 传递给完成处理程序,如捕获-list的lambda表达式或实例传递句柄的boost ::绑定的副本( )。这允许处理程序知道在其上执行操作的I / O对象,并且使得I / O对象的寿命延长到至少只要该处理程序。见Boost.Asio的异步TCP daytime服务器教程使用这种方法的一个例子。

One common idiom is to have the I/O object be managed by a single class that inherits from boost::enable_shared_from_this<>. When a class inherits from boost::enable_shared_from_this, it provides a shared_from_this() member function that returns a valid shared_ptr instance to this. A copy of the shared_ptr is passed to completion handlers, such as a capture-list in lambdas or passed as the instance handle to boost::bind(). This allows for the handlers to know the I/O object on which the operation was performed, and causes the lifetime of the I/O object to be extended to at least as long as the handler. See the Boost.Asio asynchronous TCP daytime server tutorial for an example using this approach.

class tcp_connection
  : public boost::enable_shared_from_this<tcp_connection>
{
public:

  // ...

  void start()
  {    
    boost::asio::async_write(socket_, ...,
        boost::bind(&tcp_connection::handle_write, shared_from_this(),
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred));
  }

  void handle_write(
    const boost::system::error_code& error,
    std::size_t bytes_transferred)
  {
    // I/O object is this->socket_.
  }

  tcp::socket socket_;
};

在另一方面,如果目标是要确定是否有一个处理程序之前执行其他的,则:

On the other hand, if the goal is to determine if one handler has executed before the other, then:

  • the application will need to explicitly manage the state
  • trying to manage multiple dependent call chains may be introducing unnecessary complexity and often indicates a need to reexamine the design
  • custom handlers could be used to prioritize the order in which handlers are executed. The Boost.Asio Invocation example uses custom handlers that are added to a priority queue, which are then executed at a later point in time.

这篇关于什么时候已取消的boost :: ASIO处理程序处理程序去跑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆