如何在C ++中实现协程

时间:2020-03-06 14:36:21  来源:igfitidea点击:

我怀疑它是否可以移植,但是有没有解决方案?我认为可以通过创建备用堆栈并在函数条目上重置SP,BP和IP,并让yield保存IP并恢复SP + BP来完成此操作。析构函数和异常安全性似乎很棘手,但可以解决。

完成了吗不可能吗

解决方案

COROUTINE是用于协程测序的便携式C ++库,是否为我们指明了正确的方向?似乎是一个经过时间考验的优雅解决方案.....它已有9年的历史了!

DOC文件夹中是Keld Helsgaun撰写的便携式协程测序便携式C ++库的pdf文件,其中描述了该库并提供了使用它的简短示例。

[更新]实际上,我本人正在成功使用它。好奇心使我变得更好,因此我研究了此解决方案,发现它非常适合解决我一段时间以来一直在解决的问题!

如果可能的话,使用迭代器可能比协程更好。这样,我们可以继续调用next()获取下一个值,但是我们可以将状态保留为成员变量而不是局部变量。

它可能使事情更易于维护。另一位C ++开发人员可能不会立即理解协程,而他们可能更熟悉迭代器。

我不认为C ++中有许多成熟的,干净的实现。我喜欢的一种尝试是protothread库。

是的,它可以毫无问题地完成。我们只需要一点汇编代码即可将调用堆栈移至堆上新分配的堆栈。

我会看一下boost ::协程库。

我们应该注意的一件事是堆栈溢出。在大多数操作系统上,由于虚拟内存页面未映射,因此堆栈溢出会导致段错误。但是,如果在堆上分配堆栈,则无法保证。
要时刻铭记在心。

我们应该始终考虑使用线程来代替。特别是在现代硬件中。如果我们具有可以在协例程中逻辑上分离的工作,则使用线程意味着该工作实际上可以由单独的执行单元(处理器内核)同时完成。

但是,也许我们确实想使用协程,可能是因为我们已经以这种方式编写和测试了经过良好测试的算法,或者因为我们正在移植以这种方式编写的代码。

如果我们在Windows中工作,则应查看光纤。光纤将在操作系统的支持下为我们提供类似于协程的框架。

我不熟悉其他操作系统,无法在那里推荐其他操作系统。

在POSIX上,可以使用makecontext()/ swapcontext()例程可移植地切换执行上下文。在Windows上,我们可以使用光纤API。否则,我们只需要一点胶水汇编代码即可切换机器上下文。我已经使用ASM(针对AMD64)和swapcontext()来实现了协程。两者都不是很难的。

WvCont是实现所谓的半协程的WvStreams的一部分。这些比完整的协程要容易一些:调用它,它就会返回给调用它的人。

它是使用更灵活的WvTask实现的,它支持完整的协程。我们可以在同一库中找到它。

至少可以在win32和Linux上运行,并且可能在任何其他Unix系统上运行。

它基于(原始)宏,但是以下站点提供了易于使用的生成器实现:http://www.codeproject.com/KB/cpp/cpp_generators.aspx