2015-09-15 9 views
7

Vorrei inoltrare i lavori da un thread a un ciclo di eventi asyncio (come nel caso di run_in_executor ma viceversa).Invia un lavoro a un ciclo di eventi asyncio

Ecco cosa la documentazione asyncio dice di concurrency and multithreading:

Per pianificare una richiamata da un thread diverso, il metodo BaseEventLoop.call_soon_threadsafe() è consentito. Esempio per programmare una coroutine da un thread diverso: loop.call_soon_threadsafe(asyncio.async, coro_func())

Che funziona bene ma il risultato della coroutine è perduto.

Invece, è possibile utilizzare una funzione che aggiunge un callback fatto per il futuro restituito da async (o ensure_future) in modo che il filo può accedere il risultato attraverso un concurrent.futures.Future.

C'è una ragione particolare per cui tale funzione non è implementata nella libreria standard? O mi sono perso un modo più semplice per raggiungere questo obiettivo?

risposta

6

La mia richiesta è stata completata e una funzione run_coroutine_threadsafe è stata implementata here.

Esempio:

def target(loop, timeout=None): 
    future = asyncio.run_coroutine_threadsafe(add(1, b=2), loop) 
    return future.result(timeout) 

async def add(a, b): 
    await asyncio.sleep(1) 
    return a + b 

loop = asyncio.get_event_loop() 
future = loop.run_in_executor(None, target, loop) 
assert loop.run_until_complete(future) == 3 

ho originariamente pubblicato una sotto-classe di concurrent.futures.Executor che possono ancora essere implementato come:

class LoopExecutor(concurrent.futures.Executor): 
    """An Executor subclass that uses an event loop 
    to execute calls asynchronously.""" 

    def __init__(self, loop=None): 
     """Initialize the executor with a given loop.""" 
     self.loop = loop or asyncio.get_event_loop() 

    def submit(self, fn, *args, **kwargs): 
     """Schedule the callable, fn, to be executed as fn(*args **kwargs). 
     Return a Future object representing the execution of the callable.""" 
     coro = asyncio.coroutine(fn)(*args, **kwargs) 
     return asyncio.run_coroutine_threadsafe(coro, self.loop) 
+0

vuoi mettere questo nella questione in modo che pretende molto sembra una risposta –

+0

Beh, è ​​una specie di [una risposta parziale alla mia domanda] (http://stackoverflow.com/help/self-answer), dal momento che potrebbe esserci un modo migliore per ottenere la stessa cosa. – Vincent

+0

se lo vedi in questo modo, ok :) –

Problemi correlati