2012-01-16 9 views
5

Sto provando a eseguire tre funzioni (ciascuna può richiedere fino a 1 secondo per l'esecuzione) ogni secondo. Vorrei quindi memorizzare l'output di ogni funzione e scriverlo in file separati.Eseguire più funzioni ogni secondo, scrivere il risultato nel file

Al momento sto usando Timer s per la mia gestione del ritardo. (Potrei sottoclasse Thread, ma che sta diventando un po 'complicato per questo semplice script)

def main: 
    for i in range(3): 
     set_up_function(i) 
     t = Timer(1, run_function, [i]) 
     t.start() 
    time.sleep(100) # Without this, main thread exits 

def run_function(i): 
    t = Timer(1, run_function, [i]) 
    t.start() 
    print function_with_delay(i) 

Qual è il modo migliore per gestire l'output di function_with_delay? Aggiungi il risultato a un elenco globale per ogni funzione?

Poi ho potuto mettere qualcosa di simile alla fine della mia funzione principale:

... 
while True: 
    time.sleep(30) # or in a try/except with a loop of 1 second sleeps so I can interrupt 
    for i in range(3): 
     save_to_disk(data[i]) 

Pensieri?


Edit: Aggiunta la mia risposta come una possibilità

risposta

7

Credo che il modulo python Queue sia progettato proprio per questo tipo di scenario. Si potrebbe fare qualcosa di simile, per esempio:

def main(): 
    q = Queue.Queue() 
    for i in range(3): 
     t = threading.Timer(1, run_function, [q, i]) 
     t.start() 

    while True: 
     item = q.get() 
     save_to_disk(item) 
     q.task_done() 

def run_function(q, i): 
    t = threading.Timer(1, run_function, [q, i]) 
    t.start() 
    q.put(function_with_delay(i)) 
+1

+1 Funziona perché l'output è per separare i file. Se non era banale e implicava una combinazione di output, dovevi aspettare che tutti gli elementi in coda finissero prima di scrivere. Assicurati di chiamare 'task_done' sugli oggetti che ottieni. – darvids0n

+0

Ottima idea! La coda è thread-safe ed è molto più bella di list.append (dati) –

+0

Ho aggiunto la chiamata a 'task_done' come suggerito da darvids0n. Grazie. – srgerg

1

direi memorizzare un elenco di liste (bool, str), dove bool è se la funzione ha terminato l'esecuzione e str è l'uscita. Ogni funzione blocca la lista con un mutex per aggiungere output (o se non ti interessa la sicurezza del thread ometti questo). Quindi, disporre di un semplice ciclo di polling per verificare se tutti i valori bool sono True e, in caso affermativo, effettuare le chiamate save_to_disk.

0

Un'altra alternativa potrebbe essere quella di implementare una classe (tratto da this answer) che utilizza threading.Lock(). Ciò ha il vantaggio di poter attendere sullo ItemStore e save_to_disk può utilizzare getAll anziché il polling della coda. (Più efficiente per set di dati di grandi dimensioni?)

Questo è particolarmente adatto per la scrittura in un intervallo di tempo impostato (vale a dire ogni 30 secondi), piuttosto che una volta al secondo.

class ItemStore(object): 
    def __init__(self): 
     self.lock = threading.Lock() 
     self.items = [] 

    def add(self, item): 
     with self.lock: 
      self.items.append(item) 

    def getAll(self): 
     with self.lock: 
      items, self.items = self.items, [] 
     return items 
Problemi correlati