生成器和协程如何在CPython中实现?

我已经读过在CPython中,解释器堆栈(为此目的而调用的Python函数的列表)与C堆栈(在解释器自己的代码中调用的C函数的列表)混合在一起。 如果是这样,那么如何实现生成器和协程? 他们如何记住执行状态? CPython是否将每个生成器/协程的堆栈复制到OS堆栈或从OS堆栈复制? 还是CPython只是将生成器的最高堆栈帧保留在堆上,因为生成器只能从该最高帧产生?

A. Jesse Jiryu Davis asked 2020-06-23T21:43:50Z
2个解决方案
47 votes

在运行的Python程序中将Python的堆栈和C堆栈混合在一起的说法可能会引起误解。

Python堆栈与解释器使用的实际C堆栈完全分开。 Python堆栈上的数据结构实际上是完整的Python“框架”对象(甚至可以进行自省,并在运行时更改某些属性)。 该堆栈由Python虚拟机管理,该虚拟机本身以C语言运行,因此具有正常的C程序,计算机级别的堆栈。

当使用生成器和迭代器时,解释器仅将相应的框架对象存储在Python程序堆栈之外的其他位置,并在生成器的执行恢复时将其推回那里。 这个“其他地方”就是生成器对象本身。在生成器对象上调用方法“ next”或“ send”会导致这种情况的发生。

jsbueno answered 2020-06-23T21:44:39Z
17 votes

yield指令将当前正在执行的上下文作为闭包,并将其转换为自己的活动对象。 该对象具有__iter__方法,该方法将在此yield语句之后继续。

因此,调用堆栈将转换为堆对象。

Rudi answered 2020-06-23T21:44:09Z
translate from https://stackoverflow.com:/questions/8389812/how-are-generators-and-coroutines-implemented-in-cpython