Ich versuche, zwei gleichzeitig ausgeführte Task
Objekte mit dem relativ neuen asyncio
Modul von Python 3 richtig zu verstehen und zu implementieren .
Kurz gesagt, Asyncio scheint für asynchrone Prozesse und die gleichzeitige Task
Ausführung über eine Ereignisschleife ausgelegt zu sein. Es fördert die Verwendung von await
(in asynchronen Funktionen angewendet) als rückruffreie Möglichkeit, auf ein Ergebnis zu warten und es zu verwenden, ohne die Ereignisschleife zu blockieren. (Futures und Callbacks sind immer noch eine praktikable Alternative.)
Es bietet auch die asyncio.Task()
Klasse, eine spezielle Unterklasse von Future
Coroutinen zum Umwickeln. Vorzugsweise unter Verwendung der asyncio.ensure_future()
Methode aufgerufen . Die beabsichtigte Verwendung von Asyncio-Aufgaben besteht darin, dass unabhängig ausgeführte Aufgaben "gleichzeitig" mit anderen Aufgaben innerhalb derselben Ereignisschleife ausgeführt werden können. Nach meinem Verständnis Tasks
sind diese mit der Ereignisschleife verbunden, die dann automatisch die Coroutine zwischen den await
Anweisungen steuert .
Ich mag die Idee, gleichzeitige Aufgaben verwenden zu können, ohne eine der Executor
Klassen verwenden zu müssen, aber ich habe nicht viel über die Implementierung herausgefunden.
So mache ich es gerade:
import asyncio
print('running async test')
async def say_boo():
i = 0
while True:
await asyncio.sleep(0)
print('...boo {0}'.format(i))
i += 1
async def say_baa():
i = 0
while True:
await asyncio.sleep(0)
print('...baa {0}'.format(i))
i += 1
# wrap in Task object
# -> automatically attaches to event loop and executes
boo = asyncio.ensure_future(say_boo())
baa = asyncio.ensure_future(say_baa())
loop = asyncio.get_event_loop()
loop.run_forever()
Beim Versuch, zwei Schleifenaufgaben gleichzeitig auszuführen, ist mir aufgefallen, dass die Aufgabe, sofern await
sie while
keinen internen Ausdruck hat, in der Schleife hängen bleibt und andere Aufgaben effektiv daran hindert, ausgeführt zu werden (ähnlich wie bei einer normalen while
Schleife). Sobald die Aufgaben jedoch (a) warten müssen, scheinen sie ohne Probleme gleichzeitig ausgeführt zu werden.
Somit await
scheinen die Anweisungen der Ereignisschleife einen Halt zu geben, um zwischen den Aufgaben hin und her zu wechseln, was den Effekt der Parallelität ergibt.
Beispielausgabe mit intern await
:
running async test
...boo 0
...baa 0
...boo 1
...baa 1
...boo 2
...baa 2
Beispielausgabe ohne interne await
:
...boo 0
...boo 1
...boo 2
...boo 3
...boo 4
Fragen
Gilt diese Implementierung als "richtiges" Beispiel für gleichzeitige Schleifenaufgaben asyncio
?
Ist es richtig, dass dies nur funktioniert, wenn a Task
einen Blockierungspunkt ( await
Ausdruck) bereitstellt , damit die Ereignisschleife mehrere Aufgaben jonglieren kann?
yield from
der nächsten ausgeführtyield from
.