2010-05-10 3 views
5

Scrivo su molti file in un'applicazione con thread e sto creando un gestore per file. Ho una classe HandlerFactory che gestisce la distribuzione di questi gestori. Quello che mi piacerebbe fare è cheMettere un thread in stop fino all'evento X

richieste filo A e ottiene handle di file di foo.txt dalla classe HandlerFactory

filo gestore di file richieste di B foo.txt

classe del gestore riconosce che questo handle di file è stato verificato

classe del gestore mette thread a dormire

filo B si chiude handle di file utilizzando un metodo involucro da HandlerFactory

HandlerFactory notifica dormire discussioni

filo B si sveglia e ottiene successo handle di file di foo.txt

Questo è quello che ho finora,

def get_handler(self, file_path, type): 
    self.lock.acquire() 
    if file_path not in self.handlers: 
     self.handlers[file_path] = open(file_path, type) 
    elif not self.handlers[file_path].closed: 
     time.sleep(1) 
    self.lock.release() 
    return self.handlers[file_path][type] 

Credo che questo riguarda il reperimento di sonno e conduttore con successo , ma non sono sicuro di come riattivare tutti i thread, o ancora meglio di risvegliare un thread specifico.

risposta

5

Quello che stai cercando è noto come variabile di condizione.

Condition Variables

Here è il riferimento alla libreria Python 2.
Per Python 3 può essere trovato here

+0

Questo ha finito per risolvere il mio problema, grazie. – tipu

-1

Ti rendi conto che Python ha una serratura gigante, in modo che la maggior parte dei benefici di multi-threading non si ottiene, giusto?

A meno che non ci sia un motivo per il master thread per fare qualcosa con i risultati di ciascun lavoratore, si potrebbe desiderare di prendere in considerazione solo forking fuori un altro processo per ogni richiesta. Quindi non dovrai occuparti dei problemi di blocco. Chiedi ai bambini di fare ciò che devono fare, poi muori. Se hanno bisogno di comunicare di nuovo, farlo su una pipe, con XMLRPC, o attraverso un database SQLite (che è threadsafe).

+1

Il GIL non riduce in modo significativo le prestazioni di I/O, ma solo le prestazioni di elaborazione (consultare https://wiki.python.org/moin/GlobalInterpreterLock). Poiché l'OP sembra utilizzare thread per parallelizzare l'I/O, la tua affermazione che sta perdendo la maggior parte dei vantaggi del multi-threading è ingiustificata. –

+1

Ti suggerisco di guardare la pagina 38 del file PDF di riferimento all'indirizzo http://www.dabeaz.com/python/GIL.pdf. Anche con 1 CPU, il GIL riduce il tempo di risposta dei thread associati I/O su un sistema multi-core (e talvolta su un sistema single-core), se si utilizzano più thread Python, a causa del sovraccarico di controllo di GIL. – vy32

2

Sembra che si desidera un threading.Semaphore associato ad ogni handler (altri oggetti di sincronizzazione, come eventi e condizioni sono possibili, ma un semaforo sembra più semplice per le vostre esigenze). (In particolare, utilizzare un BoundedSemaphore: per il vostro caso d'uso, che solleverà un'eccezione immediatamente per gli errori di programmazione che erroneamente rilasciano il semaphone più volte di quanto acquistano - e questo è esattamente la ragione d'essere della delimitata versione di semaphones; -).

Inizializzare ciascun semaforo su un valore di 1 quando lo si genera (in modo che il gestore sia disponibile). Ogni thread utilizza chiama acquire sul semaforo per ottenere il gestore (che potrebbe bloccarlo) e release su di esso quando viene eseguito con il gestore (che sbloccherà esattamente uno dei thread in attesa).Questo è più semplice del acquisiscono/aspettare/notifica/ciclo di vita rilascio di una condizione, e più a prova di futuro, in quanto anche come la documentazione per Condizione dicono:

L'implementazione corrente si sveglia esattamente un thread, se ce ne sono in attesa. Tuttavia, non è sicuro che si basino su questo comportamento. Un'implementazione ottimizzata per il futuro, , può richiedere occasionalmente più di un thread .

mentre con un semaforo si sta giocando sul sicuro (la semantica delle quali sono sicuri di contare su: se un semaforo è inizializzato a N, ci sono in ogni momento tra 0 e n-1 [[Compreso ]] thread che hanno acquisito correttamente il semaforo e non lo hanno ancora rilasciato).