Às vezes, há alguma operação assíncrona não crítica que precisa acontecer, mas eu não quero esperar que ela seja concluída. Na implementação de co-rotina do Tornado, você pode "disparar e esquecer" uma função assíncrona simplesmente omitindo a yield
palavra-chave.
Tenho tentado descobrir como "disparar e esquecer" com a nova async
/ await
sintaxe lançada no Python 3.5. Por exemplo, um snippet de código simplificado:
async def async_foo():
print("Do some stuff asynchronously here...")
def bar():
async_foo() # fire and forget "async_foo()"
bar()
O que acontece é que isso bar()
nunca é executado e, em vez disso, recebemos um aviso de tempo de execução:
RuntimeWarning: coroutine 'async_foo' was never awaited
async_foo() # fire and forget "async_foo()"
python
python-3.5
python-asyncio
Mike N
fonte
fonte
Respostas:
Upd:
Substitua
asyncio.ensure_future
porasyncio.create_task
qualquer lugar se estiver usando Python> = 3.7. É uma maneira mais nova e mais agradável de gerar tarefas .asyncio. Peça para “disparar e esquecer”
De acordo com a documentação do python
asyncio.Task
, é possível iniciar alguma co-rotina para executar "em segundo plano" . A tarefa criada pelaasyncio.ensure_future
função não bloqueará a execução (portanto, a função retornará imediatamente!). Parece uma forma de “disparar e esquecer” conforme solicitado.Resultado:
E se as tarefas estiverem sendo executadas após a conclusão do loop de evento?
Observe que asyncio espera que a tarefa seja concluída no momento em que o loop de eventos for concluído. Então, se você mudar
main()
para:Você receberá este aviso após a conclusão do programa:
Para evitar isso, você pode apenas aguardar todas as tarefas pendentes após a conclusão do loop de eventos:
Mate tarefas em vez de esperá-las
Às vezes, você não quer esperar que as tarefas sejam realizadas (por exemplo, algumas tarefas podem ser criadas para serem executadas para sempre). Nesse caso, você pode simplesmente cancelá-los () em vez de aguardá-los:
Resultado:
fonte
stop()
método.Obrigado, Sergey pela resposta sucinta. Aqui está a versão decorada do mesmo.
Produz
Nota: verifique minha outra resposta, que faz o mesmo usando tópicos simples.
fonte
Esta não é uma execução totalmente assíncrona, mas talvez run_in_executor () seja adequado para você.
fonte
executor
padrão será chamarconcurrent.futures.ThreadPoolExecutor.submit()
. Menciono porque a criação de threads não é gratuita; disparar e esquecer 1000 vezes por segundo provavelmente colocará uma grande pressão no gerenciamento de threadPor alguma razão, se você não puder usar
asyncio
, aqui está a implementação usando threads simples. Verifique minhas outras respostas e a resposta de Sergey também.fonte