【发布时间】:2019-12-01 11:05:09
【问题描述】:
根据以下内容,C++20 中的协程似乎将是无堆栈的。
https://en.cppreference.com/w/cpp/language/coroutines
我担心的原因有很多:
- 在嵌入式系统上,堆分配通常是不可接受的。
- 在低级代码中,嵌套 co_await 会很有用(我认为无堆栈协同程序不允许这样做)。
使用无堆栈协程,只有顶层例程可能是 暂停。该顶级例程调用的任何例程本身可能不是 暂停。这禁止在 通用库中的例程。
由于需要自定义分配器和内存池,代码更加冗长。
如果任务等待操作系统为其分配一些内存(没有内存池),则速度会变慢。
鉴于这些原因,我真的希望我对当前协程的理解非常错误。
问题分为三个部分:
- 为什么 C++ 会选择使用无堆栈协程?
- 关于在无堆栈协程中保存状态的分配。我可以使用 alloca() 来避免通常用于协程创建的任何堆分配。
协程状态通过非数组分配在堆上 新的操作员。 https://en.cppreference.com/w/cpp/language/coroutines
- 我对 c++ 协程的假设是否错误,为什么?
编辑:
我现在正在为协程进行 cppcon 会谈,如果我找到我自己问题的任何答案,我会发布它(目前还没有)。
CppCon 2014:Gor Nishanov “等待 2.0:无堆栈可恢复函数”
https://www.youtube.com/watch?v=KUhSjfSbINE
CppCon 2016:James McNellis “C++ 协程简介”
【问题讨论】:
-
堆栈式协程意味着“我分配了一个实体线程式堆栈”,而不是“我使用调用者的堆栈空间”。您混淆了两个独立的问题; stackful vs stackless,以及在自动存储中存储协程状态的能力。您对它的混淆程度使问题变得不连贯,因为大多数堆栈协同程序不能存在于其他人的堆栈中。同时对于 stackless,住在某人的自动存储中是合理的。
-
“嵌入式(非分配)生成器”部分在我看来很天真,好像它可能具有实际意义
-
@DavidLedger 所以,想象一下有人抱怨枪支管制。他们的抱怨将“无法控制射击的人”与“控制谁可以拥有枪支的规定”混为一谈。您正在使用相同的术语(无堆栈)混合两种不同的事物。确实,您的两个不同的事情都是我们可以讨论的有效问题,但是当您使用一个术语来指代两者并且似乎不理解它们是两个问题 真的很难沟通。
-
更重要的是,您所说的两个不同的“stackful”问题彼此对立。堆栈上的协程(存储在创建者的自动存储中)不会堆满,因为协程通常没有空间拥有自己的堆栈。 stackful coroutines 表示协程有一个堆栈。几乎所有存在于其创建者的自动存储中的协程实现(堆栈上协程)都将是stackless。
-
我说“通常不会堆叠”,因为我见过 setjmp/longjmp 协程将父堆栈分成几块并共享它。但这是一个可怕的 hack,它并没有真正节省任何资源并产生其他问题;这只是一种将协程破解为不支持它们的语言的方法。
标签: c++ asynchronous c++20 c++-coroutine