2009-06-23 11 views
8

Ho un sistema scritto in python che elabora grandi quantità di dati utilizzando plug-in scritti da diversi sviluppatori con diversi livelli di esperienza.Trova plug-in cpu-hogging in python multithreading

Fondamentalmente, l'applicazione avvia diversi thread di lavoro, quindi li alimenta. Ogni thread determina il plug-in da utilizzare per un elemento e chiede di elaborare l'elemento. Un plug-in è solo un modulo python con una funzione specifica definita. L'elaborazione di solito comporta espressioni regolari e non dovrebbe richiedere più di un secondo.

Occasionalmente, uno dei plug-in richiede minuti da completare, pegging la CPU al 100% per tutto il tempo. Questo di solito è causato da un'espressione regolare subottimale associata a un elemento di dati che espone tale inefficienza.

Questo è dove le cose si complicano. Se ho il sospetto di chi sia il colpevole, posso esaminare il suo codice e trovare il problema. Tuttavia, a volte non sono così fortunato.

  • Non riesco a passare da solo. Probabilmente occorrerebbe settimane per riprodurre il problema se lo faccio.
  • L'aggiunta di un timer al plug-in non aiuta, perché quando si blocca ci vuole il GIL con esso, e anche tutti gli altri plugin impiegano minuti per essere completati.
  • (Nel caso ve lo stiate chiedendo, lo SRE engine doesn't release the GIL).
  • Per quanto ne so, profiling è piuttosto inutile quando si esegue il multithreading.

Non riesco a riscrivere l'intera architettura in multiprocessing, in qualsiasi modo posso scoprire chi sta mangiando tutta la mia CPU?

AGGIUNTO: In risposta ad alcuni dei commenti:

  1. il profiling del codice multithreaded in python non è utile perché il profiler misura il tempo funzione di totale e non il tempo di CPU attiva. Prova cProfile.run ('time.sleep (3)') per vedere cosa intendo. (credito a rog [ultimo commento]).

  2. Il motivo per cui il threading singolo è difficile è perché solo un elemento in 20.000 causa il problema e non so quale sia. L'esecuzione di multithreading mi consente di esaminare 20.000 elementi in circa un'ora, mentre il thread singolo può richiedere molto più tempo (la latenza della rete è molto elevata). Ci sono altre complicazioni a cui preferirei non entrare in questo momento.

Detto questo, non è una cattiva idea per cercare di serializzare il codice specifico che chiama i plugin, in modo che i tempi di uno di essi, i tempi degli altri. Ci proverò e riferirò.

+0

Quale parte delle informazioni di profilazione è stata compromessa dal multithreading? –

+0

Puoi spiegare perché andare single-thread non funzionerà? Se i plug-in non rilasciano mai il GIL, non si verificherà alcuna elaborazione parallela e il multithreading non sarà di aiuto. –

+1

"Non posso andare a thread singolo. Probabilmente ci vorranno settimane per riprodurre il problema se lo faccio"; Sbagliato. Probabilmente andando single threaded avrai il risultato PIÙ VELOCE che thread. – nosklo

risposta

0

Come hai detto, a causa della GIL è impossibile all'interno dello stesso processo.

Si consiglia di avviare una seconda procedura di monitoraggio, che rileva i battiti di vita da un altro thread nell'app originale. Una volta che il tempo di battuta manca per un determinato periodo di tempo, il monitor può uccidere la tua app e riavviarla.

+0

Lo sto già facendo, ma non è proprio una soluzione – itsadok

0

Se suggerirebbe come si ha il controllo su struttura disabilitare tutti tranne un plugin e vedere. In sostanza, se si dispone di P1, P2 ... Pn plugin processo N corsa e P1 disabilitare in un primo momento, P2 nel secondo e così via

sarebbe molto più veloce rispetto alla corsa multithread, come nessun blocco e GIL verrai a sapere prima quale plugin è il colpevole.

3

È a quanto pare non è necessario il multithreading, solo la concorrenza, perché le discussioni che non condividono qualsiasi stato:

Prova multiprocessing invece di multithreading

Single Thread/N sottoprocessi. Qui puoi programmare ogni richiesta, poiché nessun GIL è in attesa.

Altra possibilità è quella di sbarazzarsi di più thread di esecuzione e utilizzare basato su eventi programmazione di rete (cioè utilizzare ritorto)

+0

L'altro vantaggio del multiprocessing è che sarete in grado di "vedere" il processo e ottenere il pid. – monkut

0

sarei ancora guardo suggerimento di nosklo. Puoi trovare un profilo su un singolo thread per trovare l'oggetto e ottenere il dump a lungo termine e vedere il colpevole. Sì, lo so che sono 20.000 articoli e ci vorrà molto tempo, ma a volte devi solo succhiarlo e trovare la dannata cosa per convincerti che il problema viene catturato e curato. Esegui lo script e vai a lavorare su qualcos'altro di costruttivo. Torna indietro e analizza i risultati. Questo è ciò che separa gli uomini dai ragazzi a volte ;-)

Oppure aggiungere le informazioni di registrazione che tengono traccia del tempo di esecuzione di ogni elemento mentre viene elaborato da ciascun plug-in. Guarda i dati del registro alla fine del tuo programma in esecuzione, e vedi quale impiega molto tempo per essere eseguito rispetto agli altri.