我知道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 ;线程,"所以它不适合这种实现。)
答案 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定义)。 你可以说它只是一个函数调用+存储/恢复指令和堆栈指针。 局部变量会自动保留。