Wie behandelt man eine defekte Pipe (SIGPIPE) in Python?
Ich geschrieben habe, eine einfache multi-threaded-Spiel-server in python, erstellt einen neuen thread für jede client-Verbindung. Ich finde, dass jeder jetzt und dann, die server zum Absturz bringen, da ein broken-pipe/SIGPIPE Fehler. Ich bin mir ziemlich sicher, dass es passiert, wenn das Programm versucht zu senden eine Antwort zurück an client, dass ist nicht mehr vorhanden.
Was ist ein guter Weg, um damit umzugehen? Meine bevorzugte Lösung wäre, einfach schließen Sie das server-side-Verbindung zum client und bewegen, eher als beenden Sie das gesamte Programm.
PS: Diese Frage/Antwort beschäftigt sich mit dem problem in einer Allgemeinen Weise; wie konkret soll ich es lösen?
InformationsquelleAutor der Frage Adam Plumb | 2008-10-07
Du musst angemeldet sein, um einen Kommentar abzugeben.
Lesen, auf die versuchen: - Anweisung.
InformationsquelleAutor der Antwort S.Lott
Angenommen, Sie benutzen die standard-socket-Modul, sollten Sie fangen die
socket.error: (32, 'Broken pipe')
Ausnahme (nicht IOError, wie andere vorgeschlagen haben). Dies wird in dem Fall erhoben, dass Sie ' ve beschrieben, d.h. senden/schreiben auf einen socket, für die die remote-Seite getrennt wurde.Beachten Sie, dass diese Ausnahme wird nicht immer ausgelöst werden, die auf das erste schreiben an einen geschlossenen socket - mehr in der Regel das zweite schreiben (es sei denn, die Anzahl der bytes, die geschrieben sind in dem ersten schreiben der größer ist als der socket-Puffer-Größe). Sie brauchen, um beachten Sie dies bei Ihrer Bewerbung denkt, dass das remote-Ende erhalten die Daten aus dem ersten schreiben, wenn es möglicherweise bereits getrennt haben.
Können Sie reduzieren die Inzidenz (aber nicht vollständig beseitigen) mit
select.select()
(oderpoll
). Prüfen Sie für die Daten bereit zum Lesen aus der peer vor, der versucht, eine zu schreiben. Wennselect
berichtet, dass es Daten zum Lesen aus der peer-Buchse, Lesen Sie es mitsocket.recv()
. Wenn dies eine leere Zeichenfolge zurück, die Gegenstelle hat die Verbindung geschlossen. Denn es gibt immer noch eine race-condition hier, werden Sie noch brauchen, zu fangen und behandeln der Ausnahme.Verdreht ist ideal für diese Art der Sache, aber es klingt wie Sie bereits geschrieben haben, ein gutes Stück code.
InformationsquelleAutor der Antwort mhawke
SIGPIPE
(obwohl ich denke, vielleicht meinst duEPIPE
?) tritt auf sockets, wenn Sie heruntergefahren Steckdose und dann die Daten an ihn zu senden. Die einfache Lösung nicht zu verschließen, den sockel herunter, bevor Sie versuchen, es zu senden Daten. Dies kann auch geschehen, auf den pipes, aber es klingt nicht wie das ist, was Sie erleben, da es ein Netzwerk-server.Können Sie auch nur für das band-aid-fangen Sie die Ausnahme in einigen top-level-handler in jedem thread.
Natürlich, wenn Sie verwendet Verdreht statt und erzeugt einen neuen thread für jede client-Verbindung, würden Sie wahrscheinlich nicht dieses problem haben. Es ist wirklich schwer (vielleicht unmöglich, je nach Anwendung), um die Bestellung des nah-und schreib-Operationen korrigieren, wenn mehrere threads befassen sich mit den gleichen I/O-Kanal.
InformationsquelleAutor der Antwort Glyph
Ich vor der gleichen Frage. Aber ich behaupte, dass die gleichen code das nächste mal, es funktioniert einfach.
Das erste mal brach es:
Zweiten mal funktioniert es:
Ich denke, der Grund dafür könnte sein, über die aktuelle server-Umgebung.
InformationsquelleAutor der Antwort yuan
Meine Antwort ist sehr nah an S. Lott, außer ich würde noch mehr sein, insbesondere:
wobei "23" ist die Fehler-Nummer erhalten Sie von EPIPE. Auf diese Weise werden Sie nicht versuchen, zu behandeln, Berechtigungen ein Fehler oder irgendetwas anderes, Sie sind nicht ausgestattet für.
InformationsquelleAutor der Antwort Kirk Strauser