Ich spiele mit Python asyncio
. Mein Programm hat nur drei Korotinen. Zwei von ihnen plane ich direkt, während der dritte von einem der Former geplant wird. Und ich will mein Programm richtig fertig zu stellen, wenn der Benutzer drückt Ctrl+C
:Warum wird die Eltern-Coroutine nicht abgebrochen?
import asyncio
async def coro1():
try:
print('coro1')
await asyncio.sleep(1000)
except Exception as e:
print('coro1 exc %s' % repr(e))
raise
async def coro2():
try:
print('coro2')
await asyncio.ensure_future(coro3())
await asyncio.sleep(1000)
except Exception as e:
print('coro2 exc %s' % repr(e))
raise
async def coro3():
try:
print('coro3')
await asyncio.sleep(1000)
except Exception as e:
print('coro3 exc %s' % repr(e))
raise
loop = asyncio.get_event_loop()
try:
f1 = asyncio.ensure_future(coro1())
f2 = asyncio.ensure_future(coro2())
loop.run_forever()
except KeyboardInterrupt:
print('Exiting... Cancelling all tasks')
f2.cancel()
f1.cancel()
# This code gives the same result:
# for task in asyncio.tasks.Task.all_tasks(loop):
# task.cancel()
print('Cancellation is done!')
loop.stop()
loop.run_forever()
finally:
loop.close()
Dieser Code die nächste Ausgabe erzeugt:
coro1
coro2
coro3
^CExiting... Cancelling all tasks
Cancellation is done!
coro3 exc CancelledError()
coro1 exc CancelledError()
Task was destroyed but it is pending!
task: <Task pending coro=<coro2() running at test.py:15> wait_for=<Task cancelled coro=<coro3() done, defined at test.py:23>>>
So frage ich mich, warum coro2
wurde nicht abgebrochen und coro3
tatsächlich wurde abgesagt ?
Coroutine 2 schläft weitere 1000 Sekunden, nachdem Coroutine 3 zurückkehrt. Versuchen Sie mit einer kürzeren Dauer des Schlafes (oder warten Sie 1000s!) – shongololo
@shongololo, ich fürchte, dass, selbst wenn ich "erwarten Schlaf (1000)" überhaupt löschen, das beobachtete Verhalten wird sich nicht ändern. –
Ah, ich habe die untersten Zeilen Ihres Codebeispiels (durch Scrolling verborgen) nicht gesehen. Es kann sein, dass Coroutine 2 nicht die Möglichkeit hat, die Ausnahme zurückzugeben und herunterzufahren, wenn die Schleife geschlossen wird. Sie können warten, um zu überprüfen, dass alle Aufgaben abgebrochen werden, bevor Sie die Schleife schließen, aber dann werden Sie Ihre Ausnahmen in Aktion nicht sehen ... – shongololo