2016-02-09 7 views
8

Ich habe ein Python-Programm, das mehrere (etwa 5-6) lange Abfrageanforderungen parallel sendet, wobei für jede Abfrage über Anforderungspakete unterschiedliche Threads verwendet werden. Und mir ist aufgefallen, dass einige meiner Themen manchmal einfach erstarren. Wenn dies geschieht, empfängt der Server, an den ich die Anfrage sende, die Anfrage nicht. Außerdem habe ich eine Zeitüberschreitung für die Anfrage festgelegt und es funktioniert nicht.Python-Anfragen frieren manchmal ein

try: 
    print("This line prints") 
    response = requests.head(poll_request_url, timeout=180) 
    print("This line does not print when freeze occurs") 
except ReadTimeout: 
    print("Request exception.") 
except RequestException as e: 
    print("Request exception.") 
except Exception: 
    print("Unknown exception.") 
print("This line does not print either when freeze occurs.") 

Ich mache das auf Raspberry Pi 2 Hardware mit Raspbian OS.

Ich habe das gleiche Programm ohne ein Problem, wenn ich Python 2.7 verwendet. Kürzlich bin ich zu Python 3.5 gewechselt. Ich habe beide Request-Versionen mit 2.8.1 und 2.9.1 getestet.

Dieses Problem tritt nicht sehr häufig auf, aber es passiert 2-3 mal pro Tag auf verschiedenen Threads.

Was könnte das Problem sein? Wie kann ich das debuggen?

Edit: Das Problem wird durch Aktualisieren des Linux-Kernels gelöst.

Antwort

5

Nach der Dokumentation:

http://docs.python-requests.org/en/master/user/quickstart/#timeouts

Es sollte eine Timeout Ausnahme werfen, wenn das Timeout passiert. Das würde bedeuten, dass die Zeile:

print("This line does not print when freeze occurs") 

Würde nie aufgerufen werden, es tatsächlich ein Timeout passiert.

Fangen Sie die Ausnahme? Oder irgendeine andere Ausnahme? Es könnte sein, dass es gut läuft, aber das sieht man nicht. Vielleicht versuchen Sie etwas wie folgt:

try: 
    response = requests.head(poll_request_url, timeout=180) 
except requests.exceptions.Timeout: 
    print("Timeout occurred") 

So können Sie sehen, ob das ist, was vor sich geht.

EDIT: möglicherweise ist es der "connect" Schritt, der nicht richtig ausgeht. Es kann sein, dass der große Timeout-Wert für den "Verbindungs" -Schritt es irgendwie vermasselt. Vielleicht versuchen, für die eine kürzere Timeout mit (wie hier erwähnt):

http://docs.python-requests.org/en/master/user/advanced/#timeouts

z.B.

response = requests.head(poll_request_url, timeout=(3, 180)) 

Fehlgeschlagen, dass es eine Art DNS-Lookup-Problem sein könnte? Vielleicht sehen Sie, ob das Hardcoding der IPs das gleiche Problem darstellt?

+3

Ich fange alle Ausnahmen einschließlich Timeout, und wenn Timeout passiert, fängt es die Ausnahme erfolgreich ab. Wenn die Zeitüberschreitung nicht auftritt und ein Einfrieren stattfindet, wird diese Zeile niemals ausgeführt und es wird keine Ausnahme ausgelöst. –

+0

Ich habe dem Code einen weiteren Kontext hinzugefügt, um die Ausnahmebehandlung widerzuspiegeln. –

+1

Dies muss während des "connect" -Schritts fehlschlagen - da Sie sagen, dass Sie niemals eine Anfrage auf dem Server erhalten. –

1

Mein Problem mit Timer (vom Threading Import Timer) gelöst. Wenn in den nächsten 10 Sekunden kein Ergebnis angezeigt wird - wiederholen Sie den Vorgang, wenn in den nächsten 10 Sekunden kein Ergebnis angezeigt wird - drucken Sie "Fehler" und fahren Sie fort. Sie können den Status des Timers nicht mit der if-Anweisung überwachen, wenn die Anforderung einfriert, aber Sie können dies über die while-Schleife tun und Zeit hinzufügen, wenn das Ergebnis in Ordnung ist (Python: Run code every n seconds and restart timer on condition).

Verwandte Themen