Hay una gran respuesta en StackOverflow sobre proporcionar un mejor bloqueo para los demonios (sintetizado por Eduardo Fleury ) que no depende del mecanismo común de bloqueo de archivos PID para los demonios. Hay muchos buenos comentarios sobre por qué los archivos de bloqueo PID a veces pueden causar problemas, por lo que no los volveré a mencionar aquí.
En resumen, la solución se basa en sockets de dominio de espacio de nombres abstractos de Linux, que realiza un seguimiento de los sockets por nombre para usted, en lugar de depender de archivos, que pueden quedarse después de que el demonio es SIGKILL'd. El ejemplo muestra que Linux parece liberar el socket una vez que el proceso está inactivo.
Pero no puedo encontrar documentación definitiva en Linux que diga qué hace exactamente Linux con el socket abstracto cuando el proceso enlazado es SIGKILL'd. ¿Alguien sabe?
Dicho de otra manera, ¿cuándo se libera exactamente el socket abstracto para volver a utilizarlo?
No quiero reemplazar el mecanismo del archivo PID con sockets abstractos a menos que resuelva definitivamente el problema.
fuente
Respuestas:
Sí, Linux "limpia" automáticamente los sockets abstractos en la medida en que la limpieza incluso tiene sentido. Aquí hay un ejemplo de trabajo mínimo con el que puede verificar esto:
Ejecute este programa como
./a.out /test-socket &
, luego ejecutess -ax | grep test-socket
, y verá el socket en uso. Entonceskill %./a.out
, yss -ax
mostrará que el zócalo se ha ido.Sin embargo, la razón por la que no puede encontrar esta limpieza en ninguna documentación es que realmente no se está limpiando en el mismo sentido que los sockets de dominio unix no abstractos necesitan limpieza. Un socket no abstracto en realidad asigna un inodo y crea una entrada en un directorio, que debe limpiarse en el sistema de archivos subyacente. Por el contrario, piense en un socket abstracto más como un número de puerto TCP o UDP. Claro, si vincula un puerto TCP y luego sale, ese puerto TCP estará libre nuevamente. Pero cualquier número de 16 bits que utilizó todavía existe de manera abstracta y siempre lo hizo. El espacio de nombres de los números de puerto es 1-65535 y nunca cambia ni necesita limpieza.
Entonces, piense en el nombre del socket abstracto como un número de puerto TCP o UDP, simplemente seleccionado de un conjunto mucho más grande de números de puerto posibles que parecen nombres de ruta pero no lo son. No puede enlazar el mismo número de puerto dos veces (salvo
SO_REUSEADDR
oSO_REUSEPORT
). Pero cerrar el socket (explícita o implícitamente al terminar) libera el puerto, sin nada que limpiar.fuente
Publiqué esta pregunta hace más de un año y nunca estuve muy satisfecho con la falta de documentación definitiva. Pensé en revisar la documentación de Linux nuevamente para ver si había actualizaciones, y me alegró ver esto :
Además, la interfaz de programación de Linux de Michael Kerrisk cubre la pregunta (publicada en esta otra respuesta ):
Creo que, junto con la respuesta de @ user3188445, esto aclara la pregunta con mucha precisión.
Dicho esto, todavía hay una suposición hecha aquí, que los procesos que son SIGKILL'd tendrán todos los sockets abiertos cerrados. Parece una suposición razonable, pero no tengo documentación que defina ese comportamiento.
fuente
SOCK_CLOEXEC
en caso de que algún código (incluida una biblioteca) alguna vez haga fork () + exec (). Crear procesos secundarios adicionales usando fork () sin exec () es menos común; Probablemente ya sepas si estás haciendo eso.