2014-05-15 12 views
5

Sto usando la libreria di multiprocessing di python per creare diversi processi.Unire un gruppo di processi python con un timeout

from multiprocessing import Process 
processes = [Process(target=function) for function in FUNCTIONS] 
for p in processes: 
    p.start() 

Voglio che vengano eseguiti per una certa durata e quindi se non sono stati completati, terminarli.

DURATION = 3600 

un brutto modo per farlo è la seguente (male perché se i processi finiscono più velocemente di quanto DURATA, attende ancora per tutti DURATA):

from time import sleep 
sleep(duration) 
for p in processes: 
    p.join(0) 
    p.terminate() 

Un altro brutto modo per farlo (male perché si può eventualmente prendere la N * DURATA per finire, dove N è il numero di processi):

for p in processes: 
    p.join(DURATION) 
    p.terminate() 

cosa è un buon modo per fare questo?

+1

Non so cosa stanno facendo i vostri processi ma normalmente usereste una variabile di segnalazione per segnalare al processo che è ora di finire. Quindi avresti modo DURATION, imposta il var e attendi di unirti. – RedX

risposta

2

Credo che questo faccia ciò che si desidera senza richiedere il polling e attende solo fino alla DURATA specificata.

time_waited = 0 
then = time.time() 
for p in processes: 
    if time_waited >= DURATION: 
     p.join(0) 
     p.terminate() 
    p.join(DURATION - time_waited) 
    time_waited = time.time() - then 
+0

Perché aggiorni 'then'? Puoi semplicemente avere 'time_waited = now - then' invece delle ultime due righe. – Zags

+0

Hmm sì che funzionerebbe anche bene. Suppongo che per qualche ragione il modo in cui ho avuto è stato quello che naturalmente è venuto da me prima. Forse la tua strada è un po 'più chiara però. Lo cambierò. – wubwubb

0

Questo interrogherà ogni secondo se tutti i processi sono completati, fino a DURATION. Se tutti i processi sono terminati o se DURATION si è verificato, unisce/uccide tutti i processi. Non è perfetto, in quanto ci vorrà un po 'più di un secondo in ogni iterazione del ciclo for, ma sarà piuttosto vicino.

from time import sleep 
for _ in range(DURATION): 
    if not any(i.is_alive() for i in processes): break 
    sleep(1) 
for p in processes: 
    p.join(0) 
    p.terminate() 
0

La cosa più semplice da fare è probabilmente quello di avere un filo "master" che join(0) s tutti i processi e poi esce, e hanno il thread principale join(3600) il filo master.

def wait_func(): 
    for p in processes: 
    p.join() 

wait_process = Process(target=wait_func) 
wait_process.start() 
wait_process.join(DURATION) 
for p in processes: 
    p.terminate() 
Problemi correlati