什么时候已取消的boost :: ASIO处理程序处理程序去跑? [英] When do handlers for cancelled boost::asio handlers get to run?
问题描述
升压文档<一个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:
- 应用程序将需要显式管理状态
- 要管理多个相关调用链可能会带来不必要的复杂性,通常表明有必要重新审视设计
- 自定义处理程序可用于在处理被执行的优先顺序。该Boost.Asio的<一个href=\"http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio/examples/cpp03_examples.html#boost_asio.examples.cpp03_examples.invocation\"相对=nofollow>调用的示例使用被添加到一个优先级队列中,然后在稍后的时间点执行的定制处理程序。
- 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屋!