Finde das cpu-hogging Plugin in Multithreading-Python

8

Ich habe ein in Python geschriebenes System, das große Datenmengen mit Hilfe von Plugins verarbeitet, die von verschiedenen Entwicklern mit unterschiedlichem Erfahrungsniveau geschrieben wurden.

Im Grunde startet die Anwendung mehrere Arbeitsthreads und gibt ihnen dann Daten. Jeder Thread bestimmt das Plug-in, das für einen Artikel verwendet werden soll, und fordert ihn auf, den Artikel zu verarbeiten. Ein Plug-In ist nur ein Python-Modul mit einer bestimmten definierten Funktion. Die Verarbeitung beinhaltet normalerweise reguläre Ausdrücke und sollte nicht länger als eine Sekunde dauern.

Gelegentlich benötigt eines der Plug-ins Minuten , um die CPU für die gesamte Zeit auf 100% zu setzen. Dies wird normalerweise durch einen suboptimalen regulären Ausdruck verursacht, der mit einem Datenelement gepaart ist, das diese Ineffizienz anzeigt.

Hier wird es schwierig. Wenn ich einen Verdacht habe, wer der Täter ist, kann ich seinen Code untersuchen und das Problem finden. Manchmal bin ich aber nicht so glücklich.

  • Ich kann nicht single threaded gehen. Es würde wahrscheinlich Wochen dauern, das Problem zu reproduzieren, wenn ich es tue.
  • Einen Timer auf das Plugin zu setzen, hilft nicht, denn wenn es einfriert, dauert es die GIL, und alle anderen Plugins brauchen auch ein paar Minuten.
  • (Falls Sie sich wundern, die SRE-Engine gibt die GIL nicht frei ).
  • Soweit ich das beurteilen kann Profiling ist beim Multithreading ziemlich nutzlos.

Kurz vor dem Umschreiben der gesamten Architektur in Multiprocessing, kann ich herausfinden, wer all meine CPU verbraucht?

HINZUGEFÜGT : Als Antwort auf einige der Kommentare:

  1. Das Profiling von Multithread-Code in Python ist nicht sinnvoll, da der Profiler die gesamte Funktionszeit und nicht die aktive CPU-Zeit misst. Probieren Sie cProfile.run ('time.sleep (3)') aus, um zu sehen, was ich meine. (Kredit an rog [last Kommentar]).

  2. Der Grund dafür, dass ein Singlethread schwierig ist, liegt darin, dass nur ein Element in 20.000 das Problem verursacht, und ich weiß nicht, welches es ist. Das Ausführen von Multithread ermöglicht es mir, in etwa einer Stunde 20.000 Elemente durchzugehen, während Single-Threading viel länger dauern kann (es gibt eine große Netzwerklatenz). Es gibt einige weitere Komplikationen, auf die ich im Moment lieber nicht eingehen möchte.

Das heißt, es ist keine schlechte Idee, zu versuchen, den spezifischen Code, der die Plugins aufruft, zu serialisieren, so dass das Timing von einem das Timing der anderen nicht beeinflusst. Ich werde es versuchen und melden.

    
itsadok 23.06.2009, 08:57
quelle

4 Antworten

3

Sie brauchen offensichtlich kein Multithreading, sondern nur Parallelität, da Ihre Threads keinen Status teilen:

Probieren Sie Multiprocessing anstelle von Multithreading aus

Einzelner Thread / N Subprozesse. Dort können Sie jede Anfrage zeitlich abfragen, da keine GIL gehalten wird.

Eine andere Möglichkeit besteht darin, mehrere Ausführungsthreads loszuwerden und ereignisbasierte Netzwerkprogrammierung zu verwenden (dh verdreht zu verwenden)

    
makapuf 23.06.2009 16:44
quelle
0

Wie Sie sagten, ist es wegen der GIL unmöglich innerhalb desselben Prozesses.

Ich empfehle, einen zweiten Monitor-Prozess zu starten, der auf Live-Beats von einem anderen Thread in Ihrer ursprünglichen App wartet. Wenn diese Zeit für eine bestimmte Zeit fehlt, kann der Monitor Ihre App beenden und neu starten.

    
wr. 23.06.2009 09:41
quelle
0

Wenn Sie vorschlagen, dass Sie Kontrolle über das Framework haben, deaktivieren Sie alle außer einem Plugin und sehen Sie. Grundsätzlich, wenn Sie P1, P2 ... Pn Plugins haben N-Prozess ausführen und P1 zuerst deaktivieren, P2 in der zweiten usw.

es wäre viel schneller im Vergleich zu Ihrem Multithread-Lauf, da keine GIL-Blockierung und Sie werden früher wissen, welches Plugin der Täter ist.

    
Anurag Uniyal 23.06.2009 09:52
quelle
0

Ich würde immer noch auf Nosklos Vorschlag schauen. Sie könnten in einem einzelnen Thread profilieren, um das Element zu finden, und erhalten den Dump auf lange Sicht und sehen möglicherweise den Täter. Ja, ich weiß, es sind 20.000 Dinge, und es wird eine lange Zeit dauern, aber manchmal muss man es einfach ablegen und das verdammte Ding finden, um sich davon zu überzeugen, dass das Problem aufgefangen und erledigt ist. Führen Sie das Skript aus, und arbeiten Sie an etwas Konstruktivem. Komm zurück und analysiere die Ergebnisse. Das ist es, was die Männer manchmal von den Jungen trennt ;-)

Oder / Und fügen Sie Protokollierungsinformationen hinzu, die die Zeit für die Ausführung jedes Elements bei der Verarbeitung von jedem Plug-in verfolgen. Sehen Sie sich die Protokolldaten am Ende des laufenden Programms an und sehen Sie sich an, welches Programm im Vergleich zu den anderen sehr lange benötigt.

    
Jay Atkinson 24.06.2009 02:05
quelle