2016-07-19 212 views
6

Sto giocando con concurrent.futures.Come interrompere time.sleep() in un python concurrent.futures

Attualmente il mio futuro chiama time.sleep(secs).

Sembra che lo Future.cancel() faccia meno di quanto pensassi.

Se il futuro è già in esecuzione, quindi time.sleep() non viene annullato da esso.

Lo stesso per il parametro di timeout per wait(). Non cancella il mio time.sleep().

Come annullare time.sleep() che viene eseguito in concurrent.futures?

Per il test, utilizzo lo ThreadPoolExecutor.

+0

risposta breve - in nessun modo, e molto probabilmente l'uso del sonno nei lavoratori significa problema con il design, risposta lunga - è sempre possibile implementare il sonno personalizzato con possibilità di romperli, tuttavia non è né piratonico né corretto. in alternativa è possibile verificare l'utilizzo del blocco. – Reishin

risposta

4

Se si invia una funzione a ThreadPoolExecutor, l'esecutore eseguirà la funzione in un thread e ne memorizzerà il valore di ritorno nell'oggetto Future. Poiché il numero di thread simultanei è limitato, è possibile annullare in attesa dell'esecuzione di in attesa di un futuro, ma una volta passato il controllo nel thread di lavoro al callable, non c'è modo di interrompere l'esecuzione.

Considerate questo codice:

import concurrent.futures as f 
import time 

T = f.ThreadPoolExecutor(1) # Run at most one function concurrently 
def block5(): 
    time.sleep(5) 
    return 1 
q = T.submit(block5) 
m = T.submit(block5) 

print q.cancel() # Will fail, because q is already running 
print m.cancel() # Will work, because q is blocking the only thread, so m is still queued 

In generale, ogni volta che si vuole avere qualcosa annullabili voi stessi siete responsabili per fare in modo che sia.

Esistono tuttavia alcune opzioni disponibili. Es., considerare l'utilizzo di asyncio, anche have an example using sleep. Il concetto aggira il problema, ogni volta che qualsiasi operazione potenzialmente bloccante deve essere chiamata, invece di restituire il controllo a un loop di controllo in esecuzione nel contesto più esterno, insieme a una nota che l'esecuzione dovrebbe essere continuata ogni volta che il risultato è disponibile - o, in il tuo caso, dopo che sono passati i n secondi.

+0

Oh che divertimento :-) Sono passato da multiprocessing a concurrent.futures (per altri motivi). Ora sto pensando di passare da concurrent.futures ad asyncio ... :-). Tuttavia, Phillip, grazie per la tua risposta! – guettli

+0

Sei il benvenuto Btw, con 'multiprocessing', l'interruzione di' sleep' era possibile, perché puoi ovviamente 'kill' gli altri processi. – Phillip

+0

@ Ho pensato di poter usare anche 'kill' in' concurrent.futures'. Devo solo passare da 'ThreadPoolExecutor' a ProcessPoolExecutor. O è sbagliato? – guettli

1

Non conosco molto bene sui futures concurrent, ma è possibile utilizzare questa logica per interrompere il tempo. Utilizzare un ciclo invece di sleep.time() o attendere()

for i in range(sec): 
    sleep(1) 

interruzione o pausa può essere utilizzata per uscire da loop.

+0

Sì, questo potrebbe funzionare. Sembra un ragazzo finlandese che vuole solo leggere le e-mail tramite una connessione dialup ... hmmm Ho bisogno di un ciclo degli eventi .... Ho bisogno di un programmatore .... e finalmente è un sistema operativo. – guettli