Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
取消boost::asio处理程序的处理程序何时开始运行?_Boost_Boost Asio - Fatal编程技术网

取消boost::asio处理程序的处理程序何时开始运行?

取消boost::asio处理程序的处理程序何时开始运行?,boost,boost-asio,Boost,Boost Asio,取消异步连接、发送和接收的boost文档将立即完成,取消操作的处理程序将被传递boost::asio::error::operation\u aborted error 我想知道在其他(未取消和新安排的)完成处理程序运行之前,取消的处理程序是否运行(并查看操作\u中止错误) 以下是我关注的时间线: acceptHandler和readHandler在同一事件循环和同一线程上运行 时间t0-readHandler正在oldConnectionSocket上运行 时间t1-acceptHandle

取消异步连接、发送和接收的boost文档将立即完成,取消操作的处理程序将被传递boost::asio::error::operation\u aborted error

我想知道在其他(未取消和新安排的)完成处理程序运行之前,取消的处理程序是否运行(并查看操作\u中止错误)

以下是我关注的时间线:

acceptHandler和readHandler在同一事件循环和同一线程上运行

  • 时间t0-readHandler正在oldConnectionSocket上运行
  • 时间t1-acceptHandler运行
  • 时间t2-acceptHandler调用oldConnectionSocket.cancel
  • 时间t3-acceptHandler关闭oldConnectionSocket
  • 时间t4-acceptHandler调用newConnectionSocket.async\u read(…readHandler…)
  • 调用时间t5-readHandler(从哪个上下文?)

在t5时,在调用readHandler之前,是否有可能在newConnectionSocket上下文中调用readHandler,然后在oldConnectionSocket上下文中调用该readHandler,操作被中止错误?

已取消的操作将立即发布其处理程序以进行延迟调用。但是,不保证处理程序的调用顺序。因此,
io_服务
可以选择按任意顺序调用readHandler。目前,只有a指定在某些条件下的保证顺序

在完成处理程序中,如果目标是知道哪个I/O对象与操作关联,那么考虑构造完成处理程序,使其具有对I/O对象的显式句柄。这通常通过使用以下任何一项来实现:

  • 自定义函子
  • std::bind()
    boost::bind()
  • 一个C++11lambda
一种常见的习惯用法是让I/O对象由继承自的单个类管理。当类从
boost::enable_shared_from_this
继承时,它提供了一个
shared_from_this()
成员函数,该函数将有效的
shared_ptr
实例返回到
this
shared\u ptr
的副本传递给完成处理程序,例如lambdas中的捕获列表,或者作为实例句柄传递给
boost::bind()
。这允许处理程序知道在其上执行操作的I/O对象,并导致I/O对象的生存期至少延长到与处理程序相同的长度。有关使用此方法的示例,请参见Boost.Asio教程

class-tcp\u连接
:public boost::从\u启用\u共享\u
{
公众:
// ...
void start()
{    
boost::asio::异步写入(套接字写入。。。,
boost::bind(&tcp_connection::handle_write,shared_from_this(),
boost::asio::占位符::错误,
boost::asio::占位符::字节(已传输);
}
无效句柄(
常量boost::system::error\u代码和错误,
std::大小(传输的字节数)
{
//I/O对象是这个->套接字。
}
tcp::socket-socket;
};
另一方面,如果目标是确定一个处理程序是否在另一个处理程序之前执行,则:

  • 应用程序将需要显式管理状态
  • 试图管理多个依赖的调用链可能会引入不必要的复杂性,并且通常表明需要重新检查设计
  • 自定义处理程序可用于确定处理程序执行顺序的优先级。Asio示例使用添加到优先级队列的自定义处理程序,然后在稍后的时间点执行这些处理程序

>但是,io_服务不保证处理程序的调用顺序。如果只有一个线程正在执行
io\u service::run()
,这仍然是真的吗?谢谢Tanner的详细回复。strand肯定会有用的。由于我的io_服务只在一个线程中运行,并且在计划读取之前就请求取消(显然是这样),所以是否仍然可以先运行读取完成?@crmoore是的。
io_服务
中处理程序的顺序未指定,并发级别不影响顺序。@StevenFaludi是的,仍然可以。
将保证处理程序的顺序,而不是操作。如果
acceptHandler
关闭
oldConnectionSocket
,在
newConnectionSocket
上启动读取操作,然后在
oldConnectionSocket
上启动读取操作,则未指定调用和完成读取操作的顺序。因此,调用
ReadHandler
s的顺序未指定。有关更多详细信息,请参阅答案。