Il y a une excellente réponse sur StackOverflow pour fournir un meilleur verrouillage pour les démons (synthétisé à partir d' Eduardo Fleury ) qui ne dépend pas du mécanisme de verrouillage de fichier PID commun pour les démons. Il y a beaucoup de bons commentaires sur les raisons pour lesquelles les fichiers de verrouillage PID peuvent parfois causer des problèmes, donc je ne les retravaillerai pas ici.
En bref, la solution s'appuie sur des sockets de domaine d'espace de noms abstraits Linux, qui gardent une trace des sockets par nom, plutôt que de s'appuyer sur des fichiers, qui peuvent rester après que le démon soit SIGKILL. L'exemple montre que Linux semble libérer le socket une fois le processus mort.
Mais je ne trouve pas de documentation définitive sous Linux qui indique exactement ce que fait Linux avec la socket abstraite lorsque le processus lié est SIGKILL. Est-ce que quelqu'un sait?
Autrement dit, quand précisément la prise abstraite est-elle libérée pour être réutilisée?
Je ne veux pas remplacer le mécanisme de fichier PID par des sockets abstraites à moins qu'il ne résout définitivement le problème.
la source
Réponses:
Oui, Linux "nettoie" automatiquement les sockets abstraites dans la mesure où le nettoyage est même logique. Voici un exemple de travail minimal avec lequel vous pouvez vérifier ceci:
Exécutez ce programme en tant que
./a.out /test-socket &
, puis exécutezss -ax | grep test-socket
, et vous verrez le socket utilisé. Ensuitekill %./a.out
, etss -ax
montrera que le socket a disparu.Cependant, la raison pour laquelle vous ne pouvez trouver ce nettoyage dans aucune documentation est qu'il ne nettoie pas vraiment dans le même sens que les sockets de domaine Unix non abstraits doivent être nettoyés. Un socket non abstrait alloue en fait un inode et crée une entrée dans un répertoire, qui doit être nettoyée dans le système de fichiers sous-jacent. En revanche, pensez à une socket abstraite plus comme un numéro de port TCP ou UDP. Bien sûr, si vous liez un port TCP puis quittez, ce port TCP sera à nouveau libre. Mais quel que soit le nombre 16 bits que vous avez utilisé, il existe toujours abstraitement et a toujours existé. L'espace de noms des numéros de port est 1-65535 et ne change jamais ou n'a pas besoin d'être nettoyé.
Donc, pensez simplement au nom de socket abstrait comme un numéro de port TCP ou UDP, simplement choisi parmi un ensemble beaucoup plus grand de numéros de port possibles qui ressemblent à des chemins d'accès mais qui ne le sont pas. Vous ne pouvez pas lier deux fois le même numéro de port (sauf
SO_REUSEADDR
ouSO_REUSEPORT
). Mais la fermeture du socket (explicitement ou implicitement en terminant) libère le port, sans rien à nettoyer.la source
J'ai posté cette question il y a plus d'un an et je n'ai jamais été très satisfait du manque de documentation définitive. Je pensais que je vérifierais à nouveau la documentation Linux pour toute mise à jour, et j'étais heureux de voir ceci :
De plus, l' interface de programmation Linux de Michael Kerrisk couvre la question (publiée en croix à partir de cette autre réponse ):
Je pense que, avec la réponse de @ user3188445, cela clarifie la question très précisément.
Cela dit, il y a toujours une hypothèse faite ici, que les processus qui sont SIGKILL auraient tous les sockets ouverts fermés. Cela semble une hypothèse raisonnable, mais je n'ai pas de documentation définissant ce comportement.
la source
SOCK_CLOEXEC
au cas où un code (y compris une bibliothèque) ferait jamais fork () + exec (). La création de processus enfants supplémentaires en utilisant fork () sans exec () est moins courante; vous savez probablement déjà si vous faites cela.