【问题标题】:boost asio service queue deepness and policies提升 asio 服务队列深度和策略
【发布时间】:2012-07-31 21:36:38
【问题描述】:

我了解正在运行的 asio 服务就像一个队列,我可以使用它来发布线程将按顺序执行的任务。但是,与任何队列一样,我想也有限制。是否可以为 asio 服务设置此限制?是否可以设置队列满时遵循什么策略(即阻塞、非阻塞等)?

更新

假设我有一个运行 asio::service 的线程和一个每 10 毫秒向该线程发布一个任务的计时器。任务接收绑定到一个方法调用,这将使线程休眠 100 毫秒。因此,我有一个计时器每秒向一个线程发布 100 个任务,该线程每秒能够执行 10 个任务。很明显,这种情况会有所不同。然而,在处理队列时,通常有方法来衡量队列深度(100?1000?入队的帖子等)或指定发送方在队列满时应该遵循的策略(即它应该等待还是应该丢弃请求并继续?)。我的问题是如何在 asio::service 中设置这些功能?

【问题讨论】:

  • 这个问题有点含糊,或许你可以举个例子说明一下?
  • 感谢山姆的评论。我希望现在更容易理解

标签: c++ boost boost-asio


【解决方案1】:

Asio 不提供控制内部数据结构的策略。但是,它确实提供了处理程序分配的挂钩:asio_handler_allocateasio_handler_deallocate。应用程序可以使用这些挂钩来限制未完成的异步操作的数量,以及定义达到用户指定限制时的行为。

有几个关键点需要考虑:

  • asio_handler_allocate 应该返回一个有效的内存块或者抛出一个异常。如果从asio_handler_allocate 抛出异常,它将通过io_service::post() 等调用继续展开堆栈。因此,对于达到最大值时的非阻塞行为,抛出可能是唯一的选择。
  • 考虑对组合操作的影响,例如async_read,其中asio_handler_allocateasio_handler_deallocate 可能会被多次调用。如果抛出异常,线程的堆栈将至少展开到调用io_service::run 的位置。如果发生阻塞,则有可能使所有为反应器服务的线程都被阻塞,从而基本上阻止了所有异步作业的完成。

这是来自 Boost.Asio 示例的分配 example,显示了用于处理程序的内存池。

【讨论】:

    【解决方案2】:

    我不知道。至于您的示例,最好在io_service 的线程中设置一个计时器,该计时器执行长时间运行的任务并在工作完成后重新安排自己的时间。否则你永远不会清理你的队列。如果你想要一个具有良好时序约束的实时系统——通用操作系统/编程和 boost.asio 都不能胜任这项任务。

    【讨论】:

    • 队列管理与任何多线程应用程序相关,而不仅仅是 RT
    • @Silli:是的。但是,如果你开火的次数超过了你的承受能力,而且持续不断,那么它就行不通了。在您的情况下不需要检查队列 - 您必须将计时器放在同一个队列中并在完成前一个任务时重新安排它。
    • 它(显然)是一个例子。我想知道不可预测的情况,我无法估计执行一项任务需要多少时间(例如..)
    • 哦,孩子。 ASIO 不知道如何处理来自生产者的背压。但是没有人阻止你自己做一个柜台。只需在发布时增加它,在完成时减少它。如果需要,您还可以通过将时间戳排入队列并在完成时检查它来测量延迟。我只是不明白 Asio 应该如何通用地解决这个问题。