Asynchronous 什么';s异步操作的此属性的名称。(与asio相关)

Asynchronous 什么';s异步操作的此属性的名称。(与asio相关),asynchronous,boost-asio,Asynchronous,Boost Asio,属性可以这样描述:如果操作被取消,它的处理程序将保证执行时出错 例如,不具有中所述的此属性。因此,即使取消计时器上的等待操作,其回调也有可能在没有错误的情况下执行 另一方面,该属性适用于asio套接字(至少我希望如此),因为文档中没有这样的注释) EDIT:一个伪代码,演示在截止时间计时器中缺少此属性: 1# User calls timer.async_wait with a handler H which is to be executed when the action finish

属性可以这样描述:如果操作被取消,它的处理程序将保证执行时出错

例如,不具有中所述的此属性。因此,即使取消计时器上的等待操作,其回调也有可能在没有错误的情况下执行

另一方面,该属性适用于asio套接字(至少我希望如此),因为文档中没有这样的注释)

EDIT:一个伪代码,演示在截止时间计时器中缺少此属性:

1# User calls timer.async_wait with a handler H which is to be
   executed when the action finishes.
2# Time passes.
3# Timeout has been reached, asio internally inserts the handler H into
   a queue for later execution, but with error code indicating success.
   User is unaware of when this step takes place.
4# User calls cancel on the timer, thus would expect the handler to be
   executed with an error code indicating failure.
5# Asio takes the handler H from the queue and executes it with error
   code indicating success as set in the step #3.
解决此问题很容易,只需在步骤4中设置布尔标志,然后在步骤5中检查它,因此这不是问题所在。

或都没有定义异步操作的术语,在取消时会出现保证错误。但是,包括在内的所有异步操作都表现出这种行为。处理程序的设计使其始终提供关联操作的状态。如果没有这个保证,当取消或多个操作发生时,开发人员将在处理程序中处于未知状态

取消仅适用于尚未发生的操作。我相信文档只针对计时器类强调了这一点,因为异步操作的可见性不同。I/O对象上的操作具有高可见性。例如,可以嗅探网络以观察套接字上的异步写入操作。另一方面,计时器的操作可见性较低。等待操作的机制是Boost.Asio中的一个实现细节,API不提供对操作执行外部监视的能力

在伪代码中,已达到超时,表示异步等待操作已完成。因此,不能再取消该操作,因为该操作已发生。因此,如果错误为
boost::asio::error::operation\u aborted
,则不会调用处理程序。重要的是要理解取消是一种行为,而不是状态改变。因此,无法查询计时器以查看是否发生了取消。此外,如果用户期望取消修改处理程序的错误代码,那么用户可能会迷失在继承复杂性中,这是由于异步操作的启动、完成和通知之间的时间间隔造成的


下面所有内容都非常具体地介绍了实施细节。在这个场景中,异步读取发生在使用on system的套接字上,Boost.Asio将使用epoll作为其反应器

初始化
  • 创建套接字对象时,其服务通知反应器初始化任务(
    reactor::init_task()
  • 然后,反应器将通知
    io_服务
    为任务初始化。这将导致将标记操作添加到
    io\u服务的操作队列中
  • 当套接字使用有效的文件描述符打开时,与文件描述符(
    descriptor\u data
    )关联的数据结构将注册到反应器。这个结构有它自己的操作队列,实际上它本身被视为一个操作
  • 反应堆从描述符数据中提取文件描述符,并将其添加到反应堆内要观察的文件描述符列表中
  • 异步读取操作的启动
  • 创建一个对象。此对象是操作对象。其
    perform()
    成员函数将尝试从套接字读取数据,其
    complete()
    成员函数将调用用户的完成处理程序
  • 使用读取操作调用,该操作调用
  • 反应器获取套接字的
    描述符\u数据
    ,锁定特定于描述符的互斥锁,将操作推送到特定于描述符的操作队列中,通知
    io\u服务
    有工作,然后解锁互斥锁
  • 套接字获取数据,异步读取操作的完成开始
  • 调用了io_服务::run*()
  • io_服务
    仅在任何操作准备运行时才签入其操作队列。在这种情况下,初始化期间创建的标记操作位于队列中。该操作被标识为标记,表示存在反应器,并调用
  • 反应器将在
    epoll\u wait
    上阻塞。当套接字的文件描述符具有活动时,则会识别该事件。
    descriptor\u data
    从事件中提取,并将其推送到调用方的操作队列中,因为
    descriptor\u data
    是一个操作
  • 传递回调用者的操作随后被添加到
    io\u服务的操作队列中,该队列现在包含
    描述符数据
    操作和原始标记操作
  • descriptor\u data
    操作从
    io\u服务
    队列中弹出,并调用
    complete()
    成员函数,使其运行
  • do_complete
    调用
    epoll_reactor::descriptor_state::perform_io
    ,其中在
    描述符_data
    的操作队列中迭代并调用
    perform()
    。这包括启动异步操作期间推入队列的
    boost::asio::detail::reactive_socket_recv_op
    操作
  • 读取操作的
    perform()。错误代码和传输的字节存储在操作中
  • 该操作将从
    描述符\u数据
    的操作队列中删除,并通过添加到
    io\u服务
  • 通知