使用boost::asio降低设计的复杂性

Reducing complexity of a design using boost::asio

本文关键字:复杂性 boost asio 使用      更新时间:2023-10-16

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

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

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

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

对此的典型响应是使用协同例程。

Boost Asio有两种口味:

  • 无堆栈推论

    这些都是完全协作的,不允许切换堆栈。相反,他们使用了switch语句和少数宏(yieldreenterfork)的巧妙破解。

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

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

  • 堆叠式推论

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

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

    堆叠协程通常使用boost::asio::spawn启动

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

Boost Asio具有两种风格的推论样本

  • 使用无堆栈协程实现的单线程HTTP服务器
  • 使用spawn的c++11 echo服务器
  • 与c++03样式相同