J'essaye de créer un démon en python. J'ai trouvé la question suivante , qui contient de bonnes ressources que je suis actuellement, mais je suis curieux de savoir pourquoi un double fork est nécessaire. J'ai parcouru google et trouvé de nombreuses ressources déclarant qu'il en fallait une, mais pas pourquoi.
Certains mentionnent que c'est pour empêcher le démon d'acquérir un terminal de contrôle. Comment ferait-il cela sans la deuxième fourche? Quelles sont les répercussions?
fork()
appel renvoie le PID de l'enfant au parent, il est donc facile d'obtenir le PID du processus enfant, mais pas si facile à obtenir le PID du processus petit - enfant ).Réponses:
En regardant le code référencé dans la question, la justification est:
Il s'agit donc de s'assurer que le démon est re-parenté sur init (juste au cas où le processus de lancement du démon dure longtemps), et supprime toute chance que le démon réacquiert un tty de contrôle. Donc, si aucun de ces cas ne s'applique, alors un fork devrait être suffisant. " Programmation réseau Unix - Stevens " a une bonne section à ce sujet.
la source
p=fork(); if(p) exit(); setsid()
. Dans ce cas, le parent quitte également et le premier processus enfant est reparenté. La magie double fourche est uniquement nécessaire pour empêcher le démon de l' acquisition d' un téléscripteur.forks
unchild
processus, ce tout premier processus enfant sera unsession leader
et pourra ouvrir un terminal TTY. Mais si je bifurque à nouveau à partir de cet enfant et termine ce premier enfant, le deuxième enfant fourchu ne sera pas unsession leader
et ne pourra pas ouvrir un terminal TTY. Cette affirmation est-elle correcte?setsid()
. Ainsi, le premier processus forké devient un chef de session après avoir appelésetsid()
, puis nous bifurquons à nouveau pour que le processus final à double fourche ne soit plus un leader de session. Outre l'exigence d'setsid()
être un animateur de session, vous êtes sur place.J'essayais de comprendre la double fourchette et je suis tombé sur cette question ici. Après de nombreuses recherches, c'est ce que j'ai compris. Espérons que cela aidera à clarifier les choses pour quiconque a la même question.
Sous Unix, chaque processus appartient à un groupe qui à son tour appartient à une session. Voici la hiérarchie…
Session (SID) → Groupe de processus (PGID) → Processus (PID)
Le premier processus du groupe de processus devient le chef de groupe de processus et le premier processus de la session devient le chef de session. Chaque session peut être associée à un TTY. Seul un responsable de session peut prendre le contrôle d'un TTY. Pour qu'un processus soit véritablement démonisé (exécuté en arrière-plan), nous devons nous assurer que le chef de session est tué afin qu'il n'y ait aucune possibilité que la session prenne jamais le contrôle du TTY.
J'ai exécuté le programme d'exemple de démon python de Sander Marechal à partir de ce site sur mon Ubuntu. Voici les résultats avec mes commentaires.
Notez que le processus est le chef de session après
Decouple#1
, car c'estPID = SID
. Il pourrait encore prendre le contrôle d'un TTY.Notez que ce
Fork#2
n'est plus le chef de sessionPID != SID
. Ce processus ne peut jamais prendre le contrôle d'un TTY. Vraiment démonisé.Personnellement, je trouve que la terminologie fork-two prête à confusion. Un meilleur idiome pourrait être fork-decouple-fork.
Liens d'intérêt supplémentaires:
la source
fork()
empêche déjà de créer des zombies, à condition de fermer le parent.setsid()
avant un seulfork()
? En fait, je suppose que les réponses à cette question répondent à cela.Strictement parlant, le double fork n'a rien à voir avec la re-parentalité du démon en tant qu'enfant de
init
. Tout ce qui est nécessaire pour re-parent l'enfant est que le parent doit quitter. Cela peut être fait avec une seule fourchette. De plus, faire un double fork en lui-même ne renvoie pas le processus démon àinit
; le parent du démon doit quitter. En d'autres termes, le parent se ferme toujours lors de la création d'un démon approprié pour que le processus démon soit re-parentéinit
.Alors pourquoi la double fourchette? POSIX.1-2008 Section 11.1.3, « Le terminal de contrôle », a la réponse (italiques ajoutés):
Cela nous indique que si un processus démon fait quelque chose comme ça ...
... alors le processus démon peut devenir
/dev/console
son terminal de contrôle, selon que le processus démon est un chef de session et selon l'implémentation du système. Le programme peut garantir que l'appel ci-dessus n'acquiert pas un terminal de contrôle si le programme s'assure d'abord qu'il n'est pas un chef de session.Normalement, lors du lancement d'un démon, il
setsid
est appelé (depuis le processus enfant après l'appelfork
) pour dissocier le démon de son terminal de contrôle. Cependant, appelersetsid
signifie également que le processus appelant sera le chef de session de la nouvelle session, ce qui laisse ouverte la possibilité que le démon puisse réacquérir un terminal de contrôle. La technique du double fork garantit que le processus démon n'est pas le leader de la session, ce qui garantit alors qu'un appel àopen
, comme dans l'exemple ci-dessus, n'entraînera pas la réacquisition par le processus démon d'un terminal de contrôle.La technique du double fourchette est un peu paranoïaque. Cela peut ne pas être nécessaire si vous savez que le démon n'ouvrira jamais un fichier de périphérique terminal. De plus, sur certains systèmes, cela peut ne pas être nécessaire même si le démon ouvre un fichier de périphérique terminal, car ce comportement est défini par l'implémentation. Cependant, une chose qui n'est pas définie par l'implémentation est que seul un chef de session peut allouer le terminal de contrôle. Si un processus n'est pas un chef de session, il ne peut pas allouer de terminal de contrôle. Par conséquent, si vous voulez être paranoïaque et être certain que le processus démon ne peut pas acquérir par inadvertance un terminal de contrôle, quelles que soient les spécificités définies par l'implémentation, alors la technique du double fork est essentielle.
la source
LogFile=/dev/console
. Les programmes n'ont pas toujours le contrôle à la compilation des fichiers qu'ils peuvent ouvrir;)Tiré de Bad CTK :
«Sur certaines versions d'Unix, vous êtes obligé de faire un double fork au démarrage, afin de passer en mode démon. C'est parce que le forking simple n'est pas garanti de se détacher du terminal de contrôle.
la source
setsid
après un fork initial. Il s'assure ensuite qu'il reste détaché d'un terminal de contrôle en forçant à nouveau et en faisantsetsid
quitter le chef de session (le processus qui a appelé ).fork
cela qui se détache du terminal de contrôle. C'estsetsid
ça qui le fait. Maissetsid
échouera s'il est appelé par un chef de groupe de processus. Ilfork
faut donc faire une première étape avantsetsid
de s'assurer quesetsid
c'est appelé à partir d'un processus qui n'est pas un chef de groupe de processus. Le secondfork
garantit que le processus final (celui qui sera le démon) n'est pas un chef de session. Seuls les chefs de session peuvent acquérir un terminal de contrôle, donc ce deuxième fork garantit que le démon ne réacquiert pas par inadvertance un terminal de contrôle. Cela est vrai pour tout système d'exploitation POSIX.Selon "Programmation avancée dans l'environnement Unix", par Stephens et Rago, le deuxième fork est plus une recommandation, et il est fait pour garantir que le démon n'acquiert pas de terminal de contrôle sur les systèmes basés sur System V.
la source
Une des raisons est que le processus parent peut immédiatement attendre_pid () pour l'enfant, puis l'oublier. Quand le petit-enfant meurt, son parent est init, et il attendra () pour cela - et le sortira de l'état zombie.
Le résultat est que le processus parent n'a pas besoin de connaître les enfants fourchus, et il permet également de dériver des processus longs à partir de bibliothèques, etc.
la source
L'appel daemon () a l'appel parent _exit () s'il réussit. La motivation initiale a peut-être été de permettre au parent de faire un travail supplémentaire pendant que l'enfant démonise.
Cela peut aussi être basé sur une croyance erronée selon laquelle c'est nécessaire pour s'assurer que le démon n'a pas de processus parent et qu'il est reparenté à init - mais cela se produira de toute façon une fois que le parent meurt dans le cas de la fourche unique.
Donc, je suppose que tout se résume à la tradition à la fin - une seule fourchette est suffisante tant que le parent meurt de toute façon rapidement.
la source
Une discussion décente à ce sujet semble être à l' adresse http://www.developerweb.net/forum/showthread.php?t=3025
Citant mlampkin à partir de là:
la source
Cela pourrait être plus facile à comprendre de cette manière:
la source