업데이트 :
교체 asyncio.ensure_future
로 asyncio.create_task
파이썬> = 3.7 그것은 최신의, 더 좋은 방법을 사용하고있는 모든 곳에서 경우 산란 작업에 .
asyncio.Task를 "실행하고 잊어 버리기"
파이썬 문서에 따르면 "백그라운드에서"실행asyncio.Task
하기 위해 코 루틴을 시작할 수 있습니다 . asyncio.ensure_future
함수에 의해 생성 된 작업 은 실행을 차단하지 않습니다 (따라서 함수가 즉시 반환됩니다!). 이것은 귀하가 요청한대로 "실행하고 잊어 버리는"방법처럼 보입니다.
import asyncio
async def async_foo():
print("async_foo started")
await asyncio.sleep(1)
print("async_foo done")
async def main():
asyncio.ensure_future(async_foo()) # fire and forget async_foo()
# btw, you can also create tasks inside non-async funcs
print('Do some actions 1')
await asyncio.sleep(1)
print('Do some actions 2')
await asyncio.sleep(1)
print('Do some actions 3')
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
산출:
Do some actions 1
async_foo started
Do some actions 2
async_foo done
Do some actions 3
이벤트 루프가 완료된 후 작업이 실행되면 어떻게됩니까?
asyncio는 이벤트 루프가 완료되는 순간 작업이 완료 될 것으로 예상합니다. 따라서 다음으로 변경할 경우 main()
:
async def main():
asyncio.ensure_future(async_foo()) # fire and forget
print('Do some actions 1')
await asyncio.sleep(0.1)
print('Do some actions 2')
프로그램이 완료된 후 다음 경고가 표시됩니다.
Task was destroyed but it is pending!
task: <Task pending coro=<async_foo() running at [...]
이벤트 루프가 완료된 후 모든 보류중인 작업 을 기다릴 수있는 것을 방지하려면 :
async def main():
asyncio.ensure_future(async_foo()) # fire and forget
print('Do some actions 1')
await asyncio.sleep(0.1)
print('Do some actions 2')
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
# Let's also finish all running tasks:
pending = asyncio.Task.all_tasks()
loop.run_until_complete(asyncio.gather(*pending))
작업을 기다리는 대신 종료
작업이 완료되기를 기다리지 않는 경우가 있습니다 (예 : 일부 작업은 영원히 실행되도록 생성 될 수 있음). 이 경우 기다리는 대신 cancel () 만하면됩니다.
import asyncio
from contextlib import suppress
async def echo_forever():
while True:
print("echo")
await asyncio.sleep(1)
async def main():
asyncio.ensure_future(echo_forever()) # fire and forget
print('Do some actions 1')
await asyncio.sleep(1)
print('Do some actions 2')
await asyncio.sleep(1)
print('Do some actions 3')
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
# Let's also cancel all running tasks:
pending = asyncio.Task.all_tasks()
for task in pending:
task.cancel()
# Now we should await task to execute it's cancellation.
# Cancelled task raises asyncio.CancelledError that we can suppress:
with suppress(asyncio.CancelledError):
loop.run_until_complete(task)
산출:
Do some actions 1
echo
Do some actions 2
echo
Do some actions 3
echo