Ich versuche, zwei gleichzeitig ausgeführte TaskObjekte mit dem relativ neuen asyncioModul von Python 3 richtig zu verstehen und zu implementieren .
Kurz gesagt, Asyncio scheint für asynchrone Prozesse und die gleichzeitige TaskAusfü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 Taskssind diese mit der Ereignisschleife verbunden, die dann automatisch die Coroutine zwischen den awaitAnweisungen steuert .
Ich mag die Idee, gleichzeitige Aufgaben verwenden zu können, ohne eine der ExecutorKlassen 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 awaitsie whilekeinen internen Ausdruck hat, in der Schleife hängen bleibt und andere Aufgaben effektiv daran hindert, ausgeführt zu werden (ähnlich wie bei einer normalen whileSchleife). Sobald die Aufgaben jedoch (a) warten müssen, scheinen sie ohne Probleme gleichzeitig ausgeführt zu werden.
Somit awaitscheinen 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 Taskeinen Blockierungspunkt ( awaitAusdruck) bereitstellt , damit die Ereignisschleife mehrere Aufgaben jonglieren kann?
yield fromder nächsten ausgeführtyield from.