2

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

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

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

注意:我假设我们在多个线程中调用 run()但写操作应该按顺序发送,所以我还假设写处理程序用strand包装。

感谢您的时间。

4

1 回答 1

0

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

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

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

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

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

这个答案可能会提供对组合操作和链的更多见解。

于 2013-01-31T14:34:42.557 回答