如何在fork上克隆Boost ASIO协同程序?

如何在fork上克隆Boost ASIO协同程序?,boost,boost-asio,coroutine,Boost,Boost Asio,Coroutine,查看Boost ASIO http服务器,我想知道使用的克隆方法是否安全: // We "fork" by cloning a new server coroutine to handle the connection. // After forking we have a parent coroutine and a child coroutine. Both // parent and child continue execution at the following

查看Boost ASIO http服务器,我想知道使用的克隆方法是否安全:

    // We "fork" by cloning a new server coroutine to handle the connection.
    // After forking we have a parent coroutine and a child coroutine. Both
    // parent and child continue execution at the following line. They can
    // be distinguished using the functions coroutine::is_parent() and
    // coroutine::is_child().
    fork server(*this)();
在该行中,服务器对象是从当前对象构建的副本

但不存在以下情况发生的可能性:

  • 克隆子协同程序发布一个收益
  • 这样,孩子的身体就离开了
  • 因此,子对象的
    操作符()()
    方法被保留
  • 父对象销毁子对象
  • 父级开始一个新的迭代并产生
  • 子对象调用的异步方法完成
  • 因此,现在(被破坏的)子协同程序被重新输入

  • 如果安全,为什么?

    父对象不销毁子对象

    这是因为coroutine对象是要调用的实际完成处理程序,副本保存在服务队列中

    因为字段(通常)是共享指针,所以实际数据在副本之间“轻松”移动,只有在最后一个完成处理程序完成时才会被销毁,并且协程退出,而不是屈服



    与许多其他Asio示例一样,让所有字段都成为共享指针的另一种选择可能是让协同程序派生
    从这个
    启用共享。实际上,我还没有将此应用于协同路由,但我认为它有其优点(以减少依赖于收益率的引用开销),并且不能立即想到它不适用于协同路由的原因。

    我明白了,这是安全的,因为子服务器对象是被复制的(例如,
    async\u write(…,*this)
    。您对
    启用\u共享\u的评论来自\u此
    非常准确-我基本上是在http服务器示例中查找的-因此缺少完成处理程序复制模式。我同意使用共享指针替代方案将减少开销(即,产生一个共享指针副本,而不是5个共享指针副本+1个函数对象副本+1个解析器对象副本)。