【问题标题】:Reducing complexity of a design using boost::asio使用 boost::asio 降低设计的复杂性
【发布时间】:2014-09-22 19:09:54
【问题描述】:

this question 中包含的代码显示了一组使用 boost::asio 的链式回调。在这种情况下,代码很清晰,因为链的长度很短。

在现实世界的应用程序中,回调链通常要长得多,并且必须包括超时回调和处理错误或格式错误消息的代码。这很快就变得非常复杂,类似于 1960 年代的设计,其中有太多的 goto。

可以通过将代码分层来消除一些复杂性,但由于设计是异步的,因此在某处不可避免地会出现某种类型的回调链。

是吗?有没有办法降低异步设计的复杂性? (显然在某些情况下使用线程会有所帮助,但我正在寻找单线程解决方案。)

【问题讨论】:

    标签: c++ callback boost-asio


    【解决方案1】:

    对此的典型反应是使用协同程序。

    Boost Asio 有两种风格:

    • 无堆栈协程

      这些是完全合作的,不允许切换堆栈。取而代之的是,他们采用了巧妙的 hack,包括 switch 语句和一些宏(yieldreenterfork)。

      这样做的一个缺点是协程在这个设计中是函子,并且函子需要是可复制的。为了方便起见,这邀请了涉及shared_ptrs 的选择。

      共享指针有其自身的性能开销,这可能会也可能不会影响您的应用程序。

    • 堆栈式协程

      这些仍然是协作的,但它们利用 Boost Context(通过 Boost Coroutine 库)来实际切换堆栈。这消除了前面提到的相当多的繁文缛节,但引入了另一个权衡:

      • 它可能会带来轻微的低效率;与单线程上的“平面”异步相比,它确实引入了上下文切换,具有讽刺意味的是,它类似于多线程,尽管没有线程
      • 它引入了对非标头库 Boost Context 和 Boost Coroutines 的依赖,Boost 库支持的所有目标平台都不支持

      堆栈式协程通常使用 boost::asio::spawn

      启动

    我喜欢将 Stackful Coroutines 视为一种协作式多任务抽象,可以在操作系统提供的完整线程生态系统中运行。

    Boost Asio 包含两种风格的协程示例

    【讨论】:

    • 感谢您提供如此完整的答案。这很符合要求。我在其他语言中使用过协程,但还没有在 c++ 中使用过,而且我不知道 boost 的实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-22
    • 1970-01-01
    • 1970-01-01
    • 2017-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多