开关基于协同程序
switch-based coroutines
我注意到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
,而且将包含"局部"变量。
我在用c++写。我的用例很少产生结果,所以我想只在异常处理期间更新检查点。
这个模式在实际实践中是已知的,还是仅仅作为一个好奇的记录?c++中存在可重用的实现吗?
(据我所知,Boost。协程使用不符合标准的堆栈hack,这与longjmp
多线程没有什么不同。我的应用程序很少使用协程控制流,并且在众多的"线程"中堆栈使用量可能非常高,因此不适合这样的实现。
c++中存在可重用的实现吗?
本文还讨论了驻留在Boost中的一个单头、无堆栈实现。ASIO图书馆。
另一个ASIO报头似乎表明他们比之前的状态更进一步,但我对这个不太了解。
我不久前在标准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
是的,它存在,被记录并使用在知名的分布式应用程序(Putty,但不是c++)中。
- http://www.chiark.greenend.org.uk/~ sgtatham/coroutines.html
关于Duff设备使用的另一页:
- http://research.swtch.com/duff
Duff甚至评论了这种用法,说他把它用于中断驱动状态机(现在被称为"Async"):
- http://brainwagon.org/2005/03/05/coroutines-in-c/
协例程不会破坏堆栈——它只是使用底层调用约定的调用约定(由ABI定义)。你可以说它只是一个函数调用+存储/恢复指令和堆栈指针。
- boost::asio如何生成多个协同程序,然后加入它们
- OpenGL - 在 NDC 中计算位置适用于着色器,但不适用于'regular'程序
- 安排带有上下文的协同程序
- QT 样式表主题,适用于使用属性选择器的整个应用程序
- 我可以将c ++清理器仅应用于程序的一部分而不是第三方库吗?
- 程序只适用于包含(无副作用)cout声明
- 为什么io_context在我的boost asio协同程序服务器中丢失
- Visual C++ wxWidgets应用程序仅适用于我的PC
- 使用程序集嵌入数据时"Undefined reference"错误,使用适用于窗口的 mingw-w64 编译(COFF 而不是 ELF)
- 提供依赖于输入的程序的文件路径
- 为什么我的程序仅适用于调试版本
- 用于独立于系统的程序分发的即时C++编译器
- 如何在 Windows 中保存特定于应用程序的数据
- 如何使用QT检查程序是否存在于路径中
- C 程序内存冲突依赖于 std::cout (?)
- 为什么这个C++程序适用于第一行输入,而不适用于第二行或第三行
- 如果您不编写 Web 应用程序,并且您的客户端不是浏览器,那么 Web 套接字相对于常规套接字的优势是什么?
- 适用于桌面和移动应用程序的Qt
- 与boost::property_tree XML解析器一起使用时,boost::协同程序库崩溃
- Clang编译器错误,适用于非常简单的程序