Wenn ein Python-Programm ausgeführt wird, laufen unter der Haube im Wesentlichen zwei Code-Teile.
Erstens der C-Code des CPython-Interpreters, der den Standard-C-Stack verwendet, um seine internen Stack-Frames zu speichern. Zweitens der eigentliche interpretierte Python-Bytecode, der nicht den C-Stack verwendet, sondern den Heap, um seine Stack-Frames zu speichern. Ein Greenlet ist einfach Standard-Python-Code und verhält sich daher identisch.
In einer typischen Microthreading-Anwendung gibt es Tausende, wenn nicht sogar Millionen von Microthreads (Greenlets), die überall hin wechseln. Jeder Wechsel ist im Wesentlichen gleichbedeutend mit einem Funktionsaufruf mit verzögerter Rückgabe (sozusagen) und verbraucht daher ein wenig Stack. Das Problem ist, dass der C-Stack des Interpreters früher oder später auf einen Stapelüberlauf trifft. Genau darauf zielt die Greenlet-Erweiterung ab, die Teile des Stacks vom/zum Heap hin und her schiebt, um dieses Problem zu vermeiden.
Wie Sie wissen, gibt es drei grundlegende Ereignisse bei Greenlets: einen Laichvorgang, einen Wechsel und eine Rückkehr, also lassen Sie uns diese der Reihe nach betrachten:
A) Ein Laich
Das neu erzeugte Greenlet wird mit seiner eigenen Basisadresse im Stack verbunden (wo wir uns gerade befinden). Abgesehen davon passiert nichts Besonderes. Der Python-Code des neu erzeugten Greenlets verwendet den Heap auf normale Weise, und der Interpreter verwendet weiterhin den C-Stack wie üblich.
B) Ein Schalter
Wenn ein Greenlet von einem schaltenden Greenlet umgeschaltet wird, wird der entsprechende Teil des C-Stapels (ab der Basisadresse des schaltenden Greenlets) in den Heap kopiert. Der kopierte C-Stack-Bereich wird freigegeben und die zuvor vom Interpreter des geschalteten Greenlets gespeicherten Stack-Daten werden vom Heap in den neu freigegebenen C-Stack-Bereich kopiert. Der Python-Code des umgeschalteten Greenlets nutzt den Heap weiterhin auf normale Weise. Natürlich behält der Erweiterungscode den Überblick über all diese Vorgänge (welcher Heap-Bereich zu welchem Greenlet gehört usw.).
C) Eine Rückkehr
Der Stack bleibt unangetastet und der Heap-Bereich des zurückkehrenden Greenlets wird vom Python Garbage Collector freigegeben.
Im Grunde ist dies alles, viele weitere Details und Erklärungen finden Sie unter ( http://www.stackless.com/pipermail/stackless-dev/2004-March/000022.html ) oder einfach durch Lesen des Codes, wie in Alex' Antwort beschrieben.