Heim >Backend-Entwicklung >Python-Tutorial >Python-Greenlet-Implementierungsmechanismus
In letzter Zeit verwende ich Python, um Webprogramme zu entwickeln, und verwende dann immer mehrere Threads für die Anforderungsverarbeitung. Ein Problem besteht darin, dass die Antwortzeit jeder Anforderung sichergestellt werden muss sehr kurz, sonst solange Wenn die Anfrage zu langsam ist, verweigert der Server den Dienst, da kein Thread auf die Anfrage antworten kann. Normalerweise wird unser Dienst auf Leistung getestet, wenn er online geht, sodass es im Normalfall keine großen Probleme gibt Es ist jedoch unmöglich, alle Szenarien zu testen. Wenn es erscheint, werden einige Teile nicht verfügbar sein. Später habe ich auf Coroutine und Greenlet umgestellt Ich habe ein einfaches Verständnis des Implementierungsmechanismus.
Jedes Greenlet ist nur ein Heap. Ein Python-Objekt (PyGreenlet) in . Es ist also kein Problem, Millionen oder sogar Dutzende Millionen Greenlets für einen Prozess zu erstellen >
typedef struct _greenlet { PyObject_HEAD char* stack_start; char* stack_stop; char* stack_copy; intptr_t stack_saved; struct _greenlet* stack_prev; struct _greenlet* parent; PyObject* run_info; struct _frame* top_frame; int recursion_depth; PyObject* weakreflist; PyObject* exc_type; PyObject* exc_value; PyObject* exc_traceback; PyObject* dict; } PyGreenlet;Jedes Greenlet ist eigentlich eine Funktion und speichert die Informationen, wenn diese Funktion ausgeführt wird. Für eine Funktion ist der Kontext der von ihr zugewiesene Stapel Daher können nur Greenlets mit nicht widersprüchlichen Stack-Daten diesen globalen Stack gleichzeitig verwenden. Der untere und obere Teil des Stacks werden über stack_stop und stack_start gespeichert Greenlet befindet sich derzeit im Stapel. Die Stapeldaten dieser überlappenden Greenlets müssen vorübergehend auf dem Heap gespeichert werden. Die gespeicherte Position wird über stack_copy und stack_saved aufgezeichnet, damit die Positionen von stack_stop und stack_start im Stapel zurückkopiert werden können Andernfalls werden die von der Anwendung erstellten Greenlets zerstört. Die Parallelität wird durch kontinuierliches Kopieren von Daten auf den Heap oder vom Heap auf den Stack erreicht -Typ-Anwendungen.
Das Folgende ist ein einfaches Stapelraummodell von Greenlet (von greenlet.c)
A PyGreenlet is a range of C stack addresses that must be saved and restored in such a way that the full range of the stack contains valid data when we switch to it. Stack layout for a greenlet: | ^^^ | | older data | | | stack_stop . |_______________| . | | . | greenlet data | . | in stack | . * |_______________| . . _____________ stack_copy + stack_saved . | | | | . | data | |greenlet data| . | unrelated | | saved | . | to | | in heap | stack_start . | this | . . |_____________| stack_copy | greenlet | | | | newer data | | vvv |Das Folgende ist ein einfacher Greenlet-Code
from greenlet import greenlet def test1(): print 12 gr2.switch() print 34 def test2(): print 56 gr1.switch() print 78 gr1 = greenlet(test1) gr2 = greenlet(test2) gr1.switch()