基于交换机的协同程序

时间:2014-06-13 10:10:48

标签: c++ coroutine

我知道C和C ++中协同程序的习惯用语或模式:

struct cofunctor {
    int state = 0;

    void operator () () {
        switch ( state ) {
        case 0: // Caller must initialize to 0

            if ( bar1 ) return;

            while ( bar2 ) {
        state = 1; case 1:

                if ( bar3 ) return;

        state = 2; case 2:

                if ( bar4 ) return;
            }
        state = 3; case 3:
            return;
        }
    }
};

当函数执行时,它会更新持久检查点变量。下次调用时,该值用于跳转到执行中。在实践中,检查点不仅仅是int,而是包含" local"变量

我用C ++写作。我的用例很少产生,所以我只想在异常处理期间更新检查点。

这种模式在实际操作中是否已知,或者只是记录为好奇心? C ++中是否存在可重用的实现?

(据我所知,Boost.Coroutine使用不合格的堆栈黑客,与longjmp多线程不同。我的应用程序很少会使用协程控制流,并且堆栈使用量可能非常高,而且#34 ;线程,"所以它不适合这种实现。)

4 个答案:

答案 0 :(得分:1)

  

C ++中是否存在可重用的实现?

This article还讨论了位于Boost.ASIO库中的one header无堆栈实现。

Another ASIO标题似乎表明他们已经比以前的状态更进了一步,但我对这一点并不了解。它可能与最后一个相同或不同。

答案 1 :(得分:1)

前段时间我在标准C ++中实现了可重用的堆栈协程,它允许你拥有局部变量(定义为协程类的成员)。为了调用一个协同程序(我在我的实现中称之为'光纤'),首先初始化一个用于包含状态的callstack对象,然后启动协同程序。以下是我如何定义协程的示例:

struct fiber_func_test
{ PFC_FIBER_FUNC();
  // locals
  unsigned loop_count;
  // test function
  fiber_func_test(unsigned loops_): loop_count(loops_) {}
  bool tick(fiber_callstack &fc_, ufloat &dt_)
  {
    PFC_FIBER_BODY_BEGIN
    while(loop_count--)
    {
      PFC_FIBER_CALL(fc_, dt_, fiber_func_sleep, (0.3f));
    }
    PFC_FIBER_BODY_END
  }
};

loop_count是一个局部变量,其状态存储在堆栈中。以下是它的名称:

fiber_callstack fc;
PFC_FIBER_START(fc, fiber_func_test, (10));
while(fc.tick(0.1f))
  thread_nap();

以下是代码的链接:http://sourceforge.net/p/spinxengine/code/HEAD/tree/sxp_src/core/mp/mp_fiber.h

干杯,Jarkko

答案 2 :(得分:0)

是的它存在,记录并用于众所周知且分布均匀的应用程序(Putty,而不是C ++)。

关于Duff设备使用的另一页:

Duff甚至对这个用法发表了评论,称他将它用于中断驱动状态机(现在在流行语“Async”中已知):

答案 3 :(得分:0)

boost.coroutine不会破坏堆栈 - 它只使用底层调用约定的调用约定(由ABI定义)。 你可以说它只是一个函数调用+存储/恢复指令和堆栈指针。 局部变量会自动保留。