Python-Threads Hängen
Ich habe ein einfaches threaded Python-Programm des standard-Paradigma:
class SearchThread(threading.Thread):
def __init__(self, search_queue):
threading.Thread.__init__(self)
self.search_queue = search_queue
def run(self):
while True:
try:
search_url = self.search_queue.get(timeout=15)
# <do Internet search and print output/>
except Queue.Empty:
self.search_queue.task_done()
break
except Exception, e:
print e
if __name__ == '__main__':
search_queue = Queue.Queue()
for i in range(200):
t = SearchThread(search_queue)
t.setDaemon(True)
t.start()
search_queue.join()
Die Warteschlange ist gefüllt mit über 1000 urls und einfache HTTP GET
erfolgt in <do Internet search and print output/>
. Das problem ist, dass nach der Bearbeitung zwischen 500 und 700 Einträge (dauert nur Sekunden), das Programm konsequent hängt ewig kein output, keine Ausnahme, nix.
Ich habe versucht requests
, urllib2
, urllib3
, httplib2
für die HTTP GET
aber es ändert sich nichts.
Wie prüfst du hängen threaded Python-Programm?
BTW, ich bin mit Python 2.7 unter Ubuntu 11.10 (64bit).
Bearbeiten
Bin ich genauso ratlos wie vorher, wenn starrte auf den gdb Spuren auf den hängen Prozess -
sudo gdb python 9602
GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08
...
(gdb) where
#0 0x00007fc09ea91300 in sem_wait () from /lib/x86_64-linux-gnu/libpthread.so.0
#1 0x00000000004ed001 in PyThread_acquire_lock ()
#2 0x00000000004f02de in ?? ()
#3 0x00000000004b6569 in PyEval_EvalFrameEx ()
#4 0x00000000004bcd2d in PyEval_EvalCodeEx ()
#5 0x00000000004b6a5b in PyEval_EvalFrameEx ()
#6 0x00000000004b6d77 in PyEval_EvalFrameEx ()
#7 0x00000000004bcd2d in PyEval_EvalCodeEx ()
#8 0x00000000004bd802 in PyEval_EvalCode ()
#9 0x00000000004dcc22 in ?? ()
#10 0x00000000004dd7e4 in PyRun_FileExFlags ()
#11 0x00000000004de2ee in PyRun_SimpleFileExFlags ()
#12 0x00000000004ee6dd in Py_Main ()
#13 0x00007fc09d86030d in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
#14 0x000000000041cb69 in _start ()
- Sie konnte einfügen logging-Anweisungen, um zu bestimmen, in welcher Zeile des Codes das Programm hängt sich auf.
- versuchen Sie nach dieser tutorial
- Ich hatte ein ähnliches Problem hier: stackoverflow.com/questions/28223414/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Schrieb ich ein Modul druckt threads, die hängen länger als 10 Sekunden an einer Stelle.
hanging_threads.py (Paket)
Hier ist ein Beispiel für die Ausgabe:
Diese tritt am Ausgang des Haupt-Threads, wenn Sie vergessen, um einen anderen thread als daemon.
scheint, wie Sie vor dem gleichen Problem wie bereits in diesem thread.
python-multiprocessing: einige Funktionen nicht zurückgegeben werden, wenn Sie komplett sind (Warteschlange material zu groß)
Crux ist, das ist eine ungelöste/geschlossen Fehler? http://bugs.python.org/issue8237
Ich bin mir nicht sicher, ob du immer noch das problem (die Frage ist etwas alt...).
Sieht es aus wie eine klassische deadlock (weil es scheint zu hängen bei einigen mutex-Sperre).
Für GDB gibt es ein paar nette Python-Skripten, welche die C-backtrace mit Python fordert mehr informativ. I. e. es zeigt die aktuelle Python-Aufrufe für dieses:
Ich denke, diese GDB-Python-Skripten sind auch enthalten in der original-Python-distribution. Überprüfen Sie Sie heraus.
Dann gibt es die große faulthandler-Modul bietet Sie eine Funktion, die die print-das Python-backtrace (z.B. in einem signal-handler). In mein Musikplayer Projekt, ich habe verlängert Sie ein wenig und ich benutze Sie sehr stark bei der Fehlersuche.
Beispielsweise, ich habe diese Funktion:
Und jetzt, wenn ich in GDB oder LLDB und möchte wissen, wie die aktuelle Python-threads, ich tippe einfach
p _Py_DumpTracebackAllThreads()
und es wird gedruckt auf stdout.Zusätzlich zu, dass Sie daran interessiert sind, in der C-backtrace von allen aktuellen threads, d.h.
t apply all bt full
oder so drucken Sie alle Ablaufverfolgungen in GDB.Wenn das der Python GIL, wo es hängt, es gibt wohl einige andere aktive Python-thread-was hängt für einige andere Sache. Das ist der eigentliche Fehler. Es sollte freigegeben haben die Python GIL vor.
Deine while-Schleife ist unendlich. Der thread wird nie beendet die Ausführung, auch wenn die Warteschlange leer ist.Entweder sollten Sie überprüfen Sie die queue für neue Aufgaben oder eine Nachricht an einen thread (Verwendung von Ereignis-zum Beispiel), die keine Aufgaben zu erwarten sind.
Dieser debugger debugging, Multithreading python-Programme: http://winpdb.org/
Noch eine andere Sache ist der Missbrauch der Warteschlange.bekommen. Das 1. argument ist ein boolescher Wert 'block'.
Geben Sie etwas wie:
Und, wie ich oben schrieb, vermeiden Sie Endlosschleifen. Wenn Ihr timeout abgelaufen ist, Warteschlange.Holen Sie sich hebt 'Leer' exception, die abgefangen wird, indem Sie "außer Ausnahme" (noch eine andere Konstruktion, die vermieden werden sollten, zu verwenden). Also dein loop ist wirklich unendlich. Sie Katze ändern; ausgenommen Ausnahme' für
Bearbeiten
Erste Frage war der code wie folgt