Иногда необходимо выполнить некритическую асинхронную операцию, но я не хочу ждать ее завершения. В реализации сопрограммы Tornado вы можете «запустить и забыть» асинхронную функцию, просто пропустив yield
ключевое слово.
Я пытался понять, как «выстрелить и забыть» с новым синтаксисом async
/, await
выпущенным в Python 3.5. Например, упрощенный фрагмент кода:
async def async_foo():
print("Do some stuff asynchronously here...")
def bar():
async_foo() # fire and forget "async_foo()"
bar()
Но происходит то, что он bar()
никогда не выполняется, и вместо этого мы получаем предупреждение во время выполнения:
RuntimeWarning: coroutine 'async_foo' was never awaited
async_foo() # fire and forget "async_foo()"
python
python-3.5
python-asyncio
Майк Н
источник
источник
Ответы:
UPD:
Замените
asyncio.ensure_future
наasyncio.create_task
везде, если вы используете Python> = 3.7. Это более новый и приятный способ создания задачи .asyncio.Task «выстрелил и забыл»
Согласно документации python,
asyncio.Task
можно запустить некоторую сопрограмму для выполнения «в фоновом режиме» . Задача, созданнаяasyncio.ensure_future
функцией , не будет блокировать выполнение (поэтому функция вернется немедленно!). Это похоже на способ «выстрелить и забыть», как вы просили.Вывод:
Что делать, если задачи выполняются после завершения цикла событий?
Обратите внимание, что asyncio ожидает, что задача будет завершена в момент завершения цикла событий. Итак, если вы перейдете
main()
на:Вы получите это предупреждение после завершения программы:
Чтобы предотвратить это, вы можете просто дождаться всех ожидающих задач после завершения цикла событий:
Убивайте задачи вместо того, чтобы ждать их
Иногда вы не хотите ждать выполнения задач (например, некоторые задачи могут быть созданы для вечного выполнения). В этом случае вы можете просто отменить () их вместо того, чтобы ждать их:
Вывод:
источник
stop()
методе.Спасибо Сергею за лаконичный ответ. Вот оформленная версия того же самого.
Производит
Примечание: проверьте мой другой ответ, который делает то же самое с использованием простых потоков.
источник
Это не совсем асинхронное выполнение, но, возможно, вам подойдет run_in_executor () .
источник
executor
умолчанию будет звонокconcurrent.futures.ThreadPoolExecutor.submit()
. Я упоминаю, потому что создание потоков не бесплатно; «выстрелил и забыл» 1000 раз в секунду, вероятно, сильноПо какой-то причине, если вы не можете использовать,
asyncio
то вот реализация с использованием простых потоков. Проверьте мои другие ответы и ответ Сергея тоже.источник