gpt4 book ai didi

c++ - 为什么无堆栈协程需要动态分配?

转载 作者:行者123 更新时间:2023-12-01 15:10:27 25 4
gpt4 key购买 nike

这个问题不是关于 C++20 中的协程,而是一般的协程。
这些天我正在学习 C++20 协程。我从 Coroutines Introduction 了解了堆栈式和无堆栈式协程.我也 SO-ed 以获取更多信息。
以下是我对无堆栈协程的理解:

  • 无堆栈协程在运行时确实在调用者的堆栈上具有堆栈。
  • 当它自己挂起时,由于无堆栈协程只能卡在顶层函数,它的堆栈是可预测的,有用的数据存储在一定的区域。
  • 当它不运行时,它没有堆栈。它与一个句柄绑定(bind),客户端可以通过该句柄恢复协程。

  • Coroutines TS 指定非数组 operator new在为协程帧分配存储空间时调用。但是,我认为这是不必要的,因此我提出了问题。
    一些解释/考虑:
  • 把协程的状态放在哪里呢?在句柄中,它最初存储指针。
  • 动态分配并不意味着存储在堆上。但我的意图是忽略对 operator new 的调用。 ,不管它是如何实现的。
  • 来自 cppreference :

    The call to operator new can be optimized out (even if custom allocator is used) if

    • The lifetime of the coroutine state is strictly nested within the lifetime of the caller, and

    • the size of coroutine frame is known at the call site


    对于第一个要求,如果协程比调用者生命周期长,直接将状态存储在句柄中仍然可以。
    另一方面,如果调用者不知道大小,它如何构成调用 operator new 的参数?实际上,我什至无法想象调用者在哪种情况下不知道大小。
  • 根据 this question,Rust 似乎有不同的实现。 .
  • 最佳答案

    A stackless coroutine does has stack on the caller's stack when it's running.


    那就是你误解的根源。
    基于延续的协同程序(即“无堆栈协同程序”)是一种协同程序机制,旨在能够为其他代码提供协同程序,这些代码将在某个异步进程完成后恢复其执行。这种恢复可能发生在其他一些线程中。
    因此,堆栈不能被假定为“在调用者的堆栈上”,因为调用者和调度协程恢复的进程不一定在同一个线程中。协程需要能够比调用者更长寿,因此协程的堆栈不能在调用者的堆栈上(通常。在某些 co_yield 风格的情况下,它可以)。
    协程句柄代表协程的堆栈。只要该句柄存在,协程的堆栈也存在。

    When it's not running, it doesn't have a stack. It's bound with a handle, by which the client can resume the coroutine.


    这个“句柄”如何存储协程的所有局部变量?显然它们被保留了(如果没有,那将是一个糟糕的协程机制),所以它们必须存储在某个地方。函数局部变量所在的名称称为“堆栈”。
    称它为“句柄”并不会改变它的本质。

    But my intent is to elide calls to operator new, no matter how it is implemented.


    嗯……你不能。如果从不调用 new是编写您正在编写的任何软件的重要组成部分,那么您不能使用 co_await风格的协程延续。没有一组规则可以保证省略 new在协程中。如果您使用的是特定的编译器,您可以进行一些测试以查看它省略了什么以及没有什么,但仅此而已。
    您引用的规则只是可以避免调用的情况。

    For the other, if the caller doesn't know the size, how can it compose the argument to call operator new?


    记住: co_await C++ 中的协程实际上是函数的实现细节。调用者不知道它调用的任何函数是否是协程。从外部看,所有协程都像常规函数。
    创建协程堆栈的代码发生在函数调用内部,而不是外部。

    关于c++ - 为什么无堆栈协程需要动态分配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62967789/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com