Auf StackOverflow gibt es eine großartige Antwort darauf , eine bessere Sperre für Daemons (synthetisiert von Eduardo Fleury ) bereitzustellen , die nicht vom allgemeinen PID-Dateisperrmechanismus für Daemons abhängt. Es gibt dort viele gute Kommentare darüber, warum PID-Sperrdateien manchmal Probleme verursachen können, deshalb werde ich sie hier nicht erneut aufbereiten.
Kurz gesagt, die Lösung stützt sich auf abstrakte Linux-Namespace-Domain-Sockets, die die Sockets nach Namen protokollieren, anstatt sich auf Dateien zu verlassen, die nach dem SIGKILL-Vorgang des Daemons bestehen bleiben können. Das Beispiel zeigt, dass Linux den Socket freizugeben scheint, sobald der Prozess beendet ist.
Aber ich kann in Linux keine definitive Dokumentation finden, die besagt, was genau Linux mit dem abstrakten Socket macht, wenn der gebundene Prozess SIGKILL'd ist. Weiß jemand?
Anders ausgedrückt, wann genau kann der abstrakte Socket wieder verwendet werden?
Ich möchte den PID-Dateimechanismus nicht durch abstrakte Sockets ersetzen, es sei denn, dies löst das Problem endgültig.
quelle
Antworten:
Ja, Linux "räumt" abstrakte Sockets automatisch auf, sofern das Aufräumen überhaupt Sinn macht. Hier ist ein minimales Arbeitsbeispiel, anhand dessen Sie dies überprüfen können:
Führen Sie dieses Programm als
./a.out /test-socket &
ausss -ax | grep test-socket
, und führen Sie dann aus , und Sie werden den verwendeten Socket sehen. Dannkill %./a.out
wird undss -ax
zeigen, dass die Steckdose weg ist.Der Grund, warum Sie diese Bereinigung in keiner Dokumentation finden können, ist, dass sie nicht wirklich in dem Sinne bereinigt werden kann, in dem nicht abstrakte Sockets für Unix-Domänen bereinigt werden müssen. Ein nicht-abstrakter Socket weist tatsächlich einen Inode zu und erstellt einen Eintrag in einem Verzeichnis, der im zugrunde liegenden Dateisystem bereinigt werden muss. Stellen Sie sich einen abstrakten Socket dagegen eher wie eine TCP- oder UDP-Portnummer vor. Sicher, wenn Sie einen TCP-Port binden und dann beenden, ist dieser TCP-Port wieder frei. Aber welche 16-Bit-Zahl Sie auch immer verwendet haben, sie existiert immer noch abstrakt und hat es immer getan. Der Namespace der Portnummern ist 1-65535 und muss niemals geändert oder gereinigt werden.
Stellen Sie sich also den abstrakten Socket-Namen wie eine TCP- oder UDP-Portnummer vor, die Sie aus einem viel größeren Satz möglicher Portnummern ausgewählt haben, die zwar wie Pfadnamen aussehen, dies aber nicht sind. Sie können dieselbe Portnummer nicht zweimal binden (außer
SO_REUSEADDR
oderSO_REUSEPORT
). Durch Schließen des Sockets (explizit oder implizit durch Beenden) wird der Port jedoch freigegeben, und es muss nichts mehr aufgeräumt werden.quelle
Ich habe diese Frage vor über einem Jahr gestellt und war mit dem Mangel an endgültiger Dokumentation nie ganz zufrieden. Ich dachte, ich würde die Linux-Dokumentation erneut auf Aktualisierungen überprüfen und freute mich über Folgendes :
Auch die Linux - Programmierschnittstelle von Michael Kerrisk deckt die Frage (von Cross-gepostet dieser anderen Antwort ):
Ich denke, dass dies zusammen mit der Antwort von @ user3188445 die Frage sehr genau klärt.
Trotzdem wird hier immer noch davon ausgegangen, dass Prozesse, die SIGKILL-fähig sind, alle offenen Sockets geschlossen haben. Das scheint eine vernünftige Annahme zu sein, aber ich habe keine Dokumentation, die dieses Verhalten definiert.
quelle
SOCK_CLOEXEC
falls Code (einschließlich einer Bibliothek) jemals fork () + exec () ausführt. Das Erstellen zusätzlicher untergeordneter Prozesse mit fork () ohne exec () ist seltener. Sie wissen wahrscheinlich schon, ob Sie das tun.