我怀疑它可以移植,但有没有解决方案?我认为可以通过创建备用堆栈并在功能输入上重置SP,BP和IP,并使产量保存IP并恢复SP + BP来完成.析构函数和异常安全看起来很棘手但可以解决.
它完成了吗?这不可能吗?
是的,可以毫无问题地完成.您只需要一个小的汇编代码来将调用堆栈移动到堆上新分配的堆栈.
我会看一下boost :: coroutine库.
你应该注意的一件事是堆栈溢出.在大多数操作系统上,溢出堆栈将导致段错误,因为未映射虚拟内存页.但是,如果您在堆上分配堆栈,则无法获得任何保证.要时刻铭记在心.
在POSIX上,您可以使用makecontext()/ swapcontext()例程来可移植地切换执行上下文.在Windows上,您可以使用光纤API.否则,您只需要一些胶水装配代码来切换机器上下文.我已经使用ASM(对于AMD64)和swapcontext()实现了协同程序; 既不是很难.
对于后代,
Dmitry Vyukov的网站有一个聪明的技巧,使用ucontext和setjump来模拟c ++中的协同程序.
此外,Oliver Kowalke的上下文库最近被 Boost 接受,所以我们希望很快就能看到更新版本的boost.coroutine,它可以在x86_64上运行.
没有简单的方法来实现协同程序.由于协程本身不像C/C++的堆栈抽象,就像线程一样.因此,如果没有支持语言级别更改,则无法支持它.
目前(C++ 11),所有现有的C++协程实现都基于汇编级别的黑客攻击,这些黑客攻击很难跨越平台安全可靠.为了可靠,它需要是标准的,并由编译器处理而不是黑客攻击.
有一个标准的提案 - N3708.如果您有兴趣,请查看它.
如果可能的话,使用迭代器可能比使用协程更好.这样你可以继续调用next()
以获取下一个值,但是你可以将状态保存为成员变量而不是局部变量.
它可能会使事情更易于维护.另一个C++开发人员可能不会立即理解协程,而他们可能更熟悉迭代器.
对于那些谁想要知道他们怎么可以用C利用协程在便携方式++,你将不得不等待C + +̶17的等待已经结束(见下文)!标准委员会正在研究该功能,请参阅N3722论文.总结本文的当前草案,而不是Async和Await,关键字将是可恢复的,等待.
看一下Visual Studio 2015中的实验实现,以便与Microsoft的实验实现一起使用.看起来clang还没有实现.
Cppcon Coroutines有一个很好的讨论,负面的开销抽象概述了在C++中使用Coroutines的好处,以及它如何影响代码的简单性和性能.
目前我们仍然需要使用库实现,但在不久的将来,我们将协同程序作为核心C++特性.
更新:看起来协程实现是针对C++ 20的,但是作为C++ 17(p0057r2)的技术规范发布.Visual C++,clang和gcc允许您选择使用编译时标志.
COROUTINE是一个用于协同序列的可移植C++库,是否指向正确的方向?这似乎是一个优雅的解决方案,经历了时间的考验.....它已经9岁了!
在DOC文件夹中是由Keld Helsgaun撰写的用于协同测序的便携式C++库的pdf文件,其描述了该库并提供了使用它的简短示例.
[更新]我实际上是自己成功使用它.好奇心让我变得更好,所以我研究了这个解决方案,发现它非常适合我已经工作了一段时间的问题!
我不认为在C++中有很多完整的,干净的实现.我喜欢的一个尝试是Adam Dunkels的protothread库.
另请参阅Protothreads:简化 ACM数字图书馆中受内存约束的嵌入式系统的事件驱动编程,以及Wikipedia主题Protothread中的讨论,