2011-12-05 11 views
33

私はCPythonでインタプリタスタック(この点まで到達するために呼び出されるPython関数のリスト)がCスタック(インタプリタ自身のコードで呼び出されたC関数のリスト)と混在していることを読んだことがあります。もしそうなら、どのように発電機とコルーチンが実装されていますか?実行状態をどのように覚えていますか? CPythonは、各発電機/コルーチンのスタックをOSスタックとの間でコピーしますか?あるいは、CPythonはジェネレータの最上位スタックフレームをヒープ上に保つだけです。ジェネレータはその最上位フレームからしか得られないからです。CPythonでジェネレータとコルーチンがどのように実装されていますか?

+8

私が誤って発電機やコルーチンの実装方法の説明を含んで共同編集の章でほぼ4年後に自分自身に答え:http://aosabook.org/en/500L/a-web-crawler-with-asyncio -coroutines.html –

+0

すばらしい記事、非常に高密度です。無関係な、しかし... –

+0

はどのように発生器は、このトピックにグイドと書籍の章を書くことに実装されているかについて尋ねてから、4歳未満で、手に入れましたか? :) – max

答えて

14

命令は、現在実行中のコンテキストをクロージャとして受け取り、それを自身の生存オブジェクトに変換します。このオブジェクトには__iter__メソッドがあり、これはこのyield文の後に続きます。

したがって、コールスタックはヒープオブジェクトに変換されます。

+3

Cの「ハードウェア」スタックとPythonスタックを明確にすることは重要です。なぜなら、この質問は両方を混乱させるためです。私の答えはこれを明らかにする。これは私がStackOverflowので詳細を参照したい技術的な答えのようなものである – jsbueno

37

実行中のPythonプログラム内のPythonのスタックとCスタックが混在しているという誤解を招く可能性があります。

Pythonスタックは、インタープリタによって使用される実際のCスタックより完全に分離されています。 Pythonスタックのデータ構造は、実際には完全なPythonの "フレーム"オブジェクトです(イントロスペクトされ、実行時に変更される属性もあります)。このスタックはPython仮想マシンによって管理されます。Python仮想マシン自体はC言語で動作し、通常のCプログラム、マシンレベルのスタックを持っています。

ジェネレータとイテレータを使用する場合、インタプリタは、ジェネレータとイテレータを使用するときに、それぞれのフレームオブジェクトをPythonプログラムスタック以外の場所に格納し、ジェネレータの実行を再開するときにインタプリタに戻します。この "どこか他の"はジェネレータオブジェクトです。ジェネレータオブジェクトにメソッド "next"または "send"を呼び出すと、これが発生します。

+1

- (@Rudiあなたは答えて、他の人が同様にherecheckその部分に到着するように、私はコメントを残しています、結構です)。ありがとう! – glendon

+2

私はこれを読んだ後、それを見上げ、その誰にも興味を持っている場合は、ここで[発電機のCPythonの実装](https://github.com/python/cpython/blob/master/Objects/genobject.c)です。最初にこの答えを読むことをお勧めします。これはコードが何をするのか理解するのに役立ちます。 – spectras

-2

Pythonは、VMのCスタックから完全に分離された「プログラムスタック」を維持していると主張しています。この主張は間違っています。

はリンクをチェックしてください:http://en.wikipedia.org/wiki/Stackless_Python

StacklessのPythonが存在しますが、主流ではありません。理解は、問題が正しいことです。

関連する問題