c++ “你不能在不挂起外部协程的情况下挂起外部协程中调用的内部协程”是什么意思?

snz8szmq  于 2023-04-01  发布在  其他
关注(0)|答案(1)|浏览(99)

这是Josuttis的“C++20 - The Complete Guide”中的一段话:

  • 协程是无栈的。如果不挂起外部协程,就不能挂起在外部协程中调用的内部协程。只能将外部协程作为一个整体挂起。

这是在第14章开始的时候,在任何代码片段都没有显示之前。
那是什么意思?
我知道协程在挂起点挂起,所以是挂起(以及它是一个协程而不是一个普通函数的整个事实)发生在特定的点上,那些使用co_await/co_yield/co_return的点。对我来说,这意味着是协程“决定”何时暂停。是的,无论暂停是否真正发生,接口提供给调用者的内容不仅取决于协程的主体,还取决于它的接口,即返回类型。但对我来说,仍然不是调用者决定暂停。相反,调用者决定是否应该恢复协程。
我甚至不明白如果我把它解释为“一个内部协程......不能在不挂起外部协程的情况下挂起它自己”,因为这显然是可能的(并且在书本身中有示例显示)协程f调用另一个协程g并保持恢复g直到g完成,在这一点f继续,具有从未返回到f的调用者的控件。
这就是为什么我不明白引用的文字是什么意思。此外,即使是引用的开头
协程是无栈的
我不太清楚其他方面的情况

nukf8bse

nukf8bse1#

C++协程是无栈的,这仅仅意味着它们的局部变量和“返回”地址不在普通的函数调用栈上,而是在堆上(模优化)。这提供了额外的灵活性:一个栈式协程(* 例如 *,由旧版本POSIX的swapcontext实现)显然不能被另一个(用户)线程恢复,也不能在调用它的函数中存活。
其余的描述似乎试图描述无栈协程上伴随的限制:虽然堆叠式协同程序的暂停必然是其整个协同程序的暂停(用户)线程,这样任何堆栈协程都可以(仅)将其自身和其所有调用者一起挂起,无堆栈协同程序挂起对其调用者没有直接影响(可能除了与挂起一起执行的用户模式调度之外)。这是co_await的典型函数-但它必须是显式的。特别是,这意味着在没有协程意识的情况下编写的任何通用wrapper函数都不能被挂起,这可能是采用协程的障碍,但可以有益于阅读它们。
我相信这句话的意思是说:“如果不[显式地]挂起外协程,您就不能挂起[从内部进行的操作]在外协程中调用的内协程。"但是,正如所写的那样,这似乎是对堆栈情况的更好描述(除了“不挂起整个线程”在这里更有意义),所以有可能它只是缺少了一个接续。

相关问题