Asynchronous 什么';s异步操作的此属性的名称。(与asio相关)
属性可以这样描述:如果操作被取消,它的处理程序将保证执行时出错 例如,不具有中所述的此属性。因此,即使取消计时器上的等待操作,其回调也有可能在没有错误的情况下执行 另一方面,该属性适用于asio套接字(至少我希望如此),因为文档中没有这样的注释) EDIT:一个伪代码,演示在截止时间计时器中缺少此属性: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
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_服务
仅在任何操作准备运行时才签入其操作队列。在这种情况下,初始化期间创建的标记操作位于队列中。该操作被标识为标记,表示存在反应器,并调用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服务