Nein, Co-Routinen enthalten keine Art von Threads. Co-Routinen ermöglichen kooperative Multitasking darin, dass jede Co-Routine Kontrolle freiwillig liefert. Threads andererseits wechseln zwischen Einheiten an beliebigen Punkten.
Bis zu Python 3.4 war es möglich, Co-Routinen mit Generatoren zu schreiben; Mithilfe von yield
oder yield from
Ausdrücken in einem Funktionskörper erstellen Sie stattdessen ein Generatorobjekt, wobei Code nur ausgeführt wird, wenn Sie über den Generator iterieren. Zusammen mit zusätzlichen Event-Loop-Bibliotheken (wie asyncio
) könnten Sie Co-Routinen schreiben, die einer Event-Schleife signalisieren, dass sie beschäftigt sind (vielleicht auf I/O warten) und dass eine andere Co-Routine in der Zwischenzeit:
import asyncio
import datetime
@asyncio.coroutine
def display_date(loop):
end_time = loop.time() + 5.0
while True:
print(datetime.datetime.now())
if (loop.time() + 1.0) >= end_time:
break
yield from asyncio.sleep(1)
Jedes Mal, wenn der oben genannte Code an die yield from asyncio.sleep(1)
Linie geht, ist die Ereignisschleife frei, eine andere Co-Routine, weil diese Routine für die nächste Sekunde sowieso nichts tun geht nicht laufen.
Da Generatoren können für alle Arten von Aufgaben verwendet werden, nicht nur Co-Routinen, und weil das Schreiben eine Co-Routine Generator Syntax können Ankömmlinge verwirrend sein, stellt der PEP neue Syntax, die es klarer macht dass du eine Co-Routine schreibst.
Mit dem PEP durchgeführt, die obige Probe statt wie folgt geschrieben werden kann:
noch
async def display_date(loop):
end_time = loop.time() + 5.0
while True:
print(datetime.datetime.now())
if (loop.time() + 1.0) >= end_time:
break
await asyncio.sleep(1)
Das resultierende coroutine
Objekt eine Ereignis-Schleife muss die Co-Routinen zu treiben; Eine Ereignisschleife würde await
auf jeder Co-Routine der Reihe nach, die diejenigen Co-Routinen ausführen würde, die zur Zeit nicht abgeschlossen sind.
Die Vorteile bestehen darin, dass Sie mit nativer Unterstützung auch zusätzliche Syntax zur Unterstützung von asynchronen Kontextmanagern und Iteratoren einführen können. Das Eingeben und Verlassen eines Kontextmanagers oder das Durchlaufen eines Iterators können dann zu weiteren Punkten in Ihrer Co-Routine werden, die signalisieren, dass anderer Code ausgeführt werden kann, weil etwas wieder wartet.
Co-Routinen verwenden keine Threads. –
Also, in diesem Fall, wie erreicht Python irgendeinen Vorteil aus dem Aussetzen von Ausführungen im Vergleich zu einem Generator? –
Beachten Sie, dass der PEP nur bestimmte Codes leichter codieren lässt; Mit der Syntax wird keine neue Funktionalität eingeführt. Co-Routinen * kooperieren * dadurch, dass sie das Umschalten zwischen Aufgaben an vordefinierten Punkten ermöglichen (anstatt Threads, die die Ausführung zwischen verschiedenen Einheiten an beliebigen Punkten wechseln). –