当async_write()操作永远不会结束并且涉及到某个链时会发生什么?

时间:2013-01-31 11:13:17

标签: windows asynchronous timeout boost-asio

我知道下一个 async_write()应该在前一个完成时执行(有或没有错误,但是当它完成时)。

我想知道在进行async_write()调用时会发生什么,如果其中一个由于某种原因需要很长时间甚至永远不会结束(我假设这里没有像同步操作那样的超时)。 何时此操作将被视为失败? 何时操作系统内部最终删除了永不结束的操作? 也许,是否有超时和我的假设是错误的?

我的意思是,写操作被发送到OS并且可能无限期地阻塞? 因此永远不会调用处理程序,并且永远不会调用下一个async_write()。

注意:我假设我们在几个线程中调用run()但是写操作应该按顺序发送所以我也假设写处理程序包裹着

感谢您的时间。

1 个答案:

答案 0 :(得分:0)

异步操作没有明确的超时,但可以通过IO对象的cancel()成员函数取消它们。仅当底层OS调用本身以不合理发生重试的方式失败时,这些操作才会被视为失败。例如,如果写入失败:

  • EINTR,然后立即重新尝试写入。
  • EWOULDBLOCKEAGAINERROR_RETRY,然后Boost.Asio会将操作推回到作业队列中。如果写入缓冲区已满,则可能会发生这种情况,因此将操作推回队列会延迟其重新尝试,从而允许尝试其他操作。
  • 其他错误将导致操作失败。

系统调用中不应无限期阻塞。 Boost.Asio将基础IO对象设置为非阻塞,并通过在EWOULDBLOCKEAGAINERROR_RETRY写入失败时等待关联的文件描述符来提供同步阻塞写入行为。

链不受长期异步操作的影响。 Strands用于提供对处理程序的严格顺序调用,而不是操作本身。对于组合操作(例如boost::asio::async_write),中间处理程序也将通过与最终处理程序相同的链调用。总的来说,这种行为有助于提供线程安全性,如:

  • 从中间处理程序启动的所有async_write_some操作都属于链内。
  • 操作本身不属于束缚。这允许其他处理程序在实际写入时运行。
  • 将在链中调用用户处理程序。

这个answer可以提供对组合操作和线索的更多洞察。