2015-05-31 6 views
5

Ho problemi a capire come aggiungere una nuova attività a un ciclo di eventi già in esecuzione.comprensione asyncio già in esecuzione ciclo continuo e attività in sospeso

Questo codice:

import asyncio 
import logging 

@asyncio.coroutine 
def blocking(cmd): 
    while True: 
     logging.info("in blocking coroutine") 
     yield from asyncio.sleep(0.01) 
     print("ping") 

def main(): 
    logging.info("in main funciton") 
    loop = asyncio.get_event_loop() 
    logging.info("new loop created") 
    logging.info("loop running forever") 
    loop.run_forever() 
    asyncio.async(blocking("ls")) 

logging.basicConfig(level = logging.INFO) 
main() 

Modifica run_forever() a run_until_complete(asyncio.async(blocking("ls")) funziona bene. Ma sono davvero confuso - perché non riesco a pendere un compito sul loop già in esecuzione?

risposta

10

Il problema è che la chiamata ai blocchi loop.run_forever(); avvia il ciclo degli eventi e non ritorna finché non interrompi esplicitamente il ciclo, quindi la parte forever di run_forever. Il tuo programma non interrompe mai esplicitamente il ciclo degli eventi, quindi la tua chiamata asyncio.async(blocking("ls")) non viene mai raggiunta.

L'utilizzo di asyncio.async per aggiungere una nuova attività a un ciclo già in esecuzione va bene, è sufficiente assicurarsi che la funzione venga effettivamente chiamata da una coroutine o richiamata all'interno del ciclo degli eventi. Ecco alcuni esempi:

Schedule blocking a correre non appena il ciclo degli eventi inizia:

def main(): 
    logging.info("in main funciton") 
    loop = asyncio.get_event_loop() 
    logging.info("new loop created") 
    logging.info("loop running forever") 
    asyncio.async(blocking("ls")) 
    loop.run_forever() 

Schedule blocking da un callback eseguito dal ciclo di eventi:

def start_blocking(): 
    asyncio.async(blocking("ls")) 

def main(): 
    logging.info("in main funciton") 
    loop = asyncio.get_event_loop() 
    logging.info("new loop created") 
    logging.info("loop running forever") 
    loop.call_soon(start_blocking) # Calls start_blocking once the event loop starts 
    loop.run_forever() 
Problemi correlati