Was ist der Grund für die Durchführung einer Doppel-Gabel, die beim erstellen ein Dämon?
Ich versuche zu schaffen, einen daemon in python. Ich habe festgestellt, das folgende Frage, die hat einige gute Ressourcen, die ich bin derzeit auf der folgenden, aber ich bin neugierig, warum ein Doppel-Gabel notwendig ist. Ich habe zerkratzt rund um google und finden jede Menge Ressourcen, die erklärt, dass man notwendig ist, aber nicht warum.
Einige erwähnen, dass es, um zu verhindern, dass der daemon vom Erwerb einer kontrollierenden terminal. Wie würden Sie dies tun, ohne die zweite Gabel? Was sind die Auswirkungen?
- stackoverflow.com/questions/10932592/why-fork-twice/...
- Eine Schwierigkeit mit einem Doppelklick Gabel ist, dass die Eltern nicht einfach die PID von der Enkel-Prozess (der
fork()
Aufruf gibt dem Kind die PID der Eltern, so dass es leicht zu Holen Sie sich die PID des child-Prozesses, aber nicht so einfach, um die PID der Enkel-Prozess).
Du musst angemeldet sein, um einen Kommentar abzugeben.
Blick auf den code verwiesen, in der Frage der Rechtfertigung ist:
So ist es, sicherzustellen, dass der daemon neu-übergeordnet auf init (nur im Falle der Prozess-Auftakt der daemon ist lange lebte), und entfernt jede chance der daemon reacquiring ein controlling tty. Also, wenn keiner dieser Fälle zutrifft, dann eine Gabel sollte ausreichend sein. "Unix Network Programming - Stevens" hat einen guten Teil auf dieses.
p=fork(); if(p) exit(); setsid()
. In diesem Fall werden die Eltern auch beendet und das erste Kind-Prozess wird reparented. Die Doppel-Gabel Magie ist nur erforderlich, um zu verhindern, dass der daemon vom Erwerb einer tty.forks
einechild
dabei, das erste Kind Prozess wird einsession leader
und wird in der Lage sein, um öffnen Sie ein TTY-terminal. Aber wenn ich die Gabel wieder von diesem Kind und kündigen Sie das erste Kind, das zweite Gabel Kind nicht einsession leader
und nicht in der Lage zu öffnen, ein TTY-terminal. Ist diese Aussage korrekt?setsid()
. So, die erste Gabel Prozess wird ein session leader nach dem Aufrufsetsid()
und dann haben wir die Gabel wieder, so dass die endgültige, Doppel-Gabel-Prozess ist nicht länger ein session leader. Außer der Anforderung vonsetsid()
zu einer Sitzung Führungskraft sind Sie vor Ort auf.Ich versuche zu verstehen, was die Doppel-Gabel-und stolperte über diese Frage hier. Nach viel Forschung das ist, was ich herausgefunden. Hoffentlich wird es helfen, zu klären, die Dinge besser für alle, die die gleiche Frage stellen.
In Unix jeder Prozess gehört zu einer Gruppe, die wiederum gehört zu einer session. Hier ist die Hierarchie...
Sitzung (SID) - → - Prozess-Gruppe (PGID) → Prozess (PID)
Den ersten Prozess in der Gruppe Prozess wird die Prozess-Gruppenleiter, und der erste Prozess in der session wird die session-Führer. Jede Sitzung kann eine TTY zugeordnet. Lediglich eine session-Führer die Kontrolle über eine TTY-Schnittstelle. Für einen Prozess, um wirklich daemonisierte (lief im hintergrund) wir sollten dafür sorgen, dass die session-Führer getötet wird, so dass es keine Möglichkeit gibt, die Sitzung immer die Kontrolle über das TTY.
Ich lief Sander Marechal ' s python-Beispiel daemon-Programm von diese Website auf meinem Ubuntu. Hier sind die Ergebnisse mit meinen Kommentaren.
Beachten Sie, dass der Prozess der session leader nach
Decouple#1
, weil esPID = SID
. Es könnte immer noch die Kontrolle über ein TTY.Beachten Sie, dass
Fork#2
ist nicht mehr der session leaderPID != SID
. Dieser Prozess kann nie die Kontrolle über ein TTY. Wirklich daemonisierte.Ich persönlich finde Terminologie Gabel-doppelt verwirrend. Ein besseres idiom sein könnte, Gabel-entkoppeln-Gabel.
Weitere links von Interesse:
fork()
verhindert schon die Erstellung zombies, sofern Sie in der Nähe der Eltern.setsid()
bevor ein einzelnesfork()
? Eigentlich denke ich, die Antworten von diese Frage beantworten.Streng genommen, den Doppel-Gabel hat nichts zu tun mit re-parenting, den daemon als Kind
init
. Alles, was notwendig ist, um re-Elternteil das Kind, dass die Eltern beenden muss. Diese kann getan werden, mit nur einer Gabel. Auch, dabei eine Doppel-Gabel selbst nicht re-Eltern-der daemon-Prozess zuinit
; der Dämon ist die Muttergesellschaft der muss beenden. In anderen Worten, die Eltern immer beendet, wenn die Verzweigung eine richtige daemon, so dass der daemon-Prozess wird re-übergeordnet zuinit
.Also warum das Doppel-Gabel? POSIX.1-2008 Abschnitt 11.1.3, "Das Controlling Terminal", hat die Antwort (Hervorhebung Hinzugefügt):
Dies sagt uns, dass, wenn ein Dämon-Prozess, der soetwas macht ...
... dann wird der daemon-Prozess könnte erwerben
/dev/console
als Ihre Kontroll-terminal, je nachdem, ob Sie den Dämon-Prozess ist eine "session leader", und abhängig von der system-Implementierung. Das Programm kann Garantie, dass Sie die oben genannten Aufruf nicht den Erwerb einer kontrollierenden terminal, wenn das Programm zuerst sicher, dass es nicht eine "session leader".Normalerweise beim starten eines Daemons
setsid
aufgerufen wird (von der Kind-Prozess nach dem Aufruf vonfork
) zu distanzieren, die der daemon seine kontrollierenden terminal. Allerdings ruftsetsid
auch bedeutet, dass der aufrufende Prozess wird die Sitzung Führer der neuen Sitzung, die die Möglichkeit offen lässt, dass der daemon konnte erneut einen kontrollierenden terminal. Die Doppel-Gabel-Technik sorgt dafür, dass der daemon-Prozess ist nicht der "session leader", die dann garantiert, dass ein Aufrufopen
wie in dem Beispiel oben nicht dazu führen, dass der daemon-Prozess reacquiring ein kontrollierendes terminal.Den Doppel-Gabel-Technik ist ein bisschen paranoid. Es kann nicht notwendig sein, wenn Sie wissen, dass der daemon wird nie öffnen Sie ein terminal-Gerätedatei. Auch, auf einigen Systemen kann es notwendig sein, auch wenn der daemon nicht öffnen Sie eine terminal-Geräte-Datei, da dieses Verhalten wird durch die Implementierung festgelegt. Jedoch, eine Sache, die nicht durch die Implementierung festgelegt ist, dass nur eine "session leader" zuordnen kann, das controlling terminal. , Wenn ein Prozess nicht eine "session leader" ist, kann es nicht zuordnen, einem kontrollierenden terminal. Deshalb, wenn Sie möchten, werden Sie paranoid und sicher sein, dass der daemon-Prozess nicht versehentlich den Erwerb einer kontrollierenden terminal, unabhängig von der Implementierung definierte Besonderheiten, dann die Doppel-Gabel-Technik ist unerlässlich.
LogFile=/dev/console
. Programme haben nicht immer die compile-Zeit die Kontrolle darüber, welche Dateien Sie öffnen konnte 😉Entnommen Bad CTK:
"Auf einigen Unix-Geschmacksrichtungen, sind Sie gezwungen, zu tun, ein Doppel-Gabel auf Start, um zu gehen in daemon-Modus. Dies ist, weil einzelne Verzweigung ist nicht garantiert, lösen sich vom controlling terminal."
setsid
nach einer ersten Gabel. Ist es dann gewährleistet, dass es bleibt löst sich vom controlling terminal durch "forking" wieder und mit der "session leader" (der Prozess, genanntsetsid
) beenden.fork
dass löst sich vom kontrollierenden terminal. Es istsetsid
dass es tut. Abersetsid
wird scheitern, wenn es heißt, die aus einem Prozess, den Anführer der Gruppe. So eine erstefork
getan werden muss, bevorsetsid
um sicherzustellen, dasssetsid
genannt wird, von einem Prozess, ist nicht ein Prozess, den Anführer der Gruppe. Die zweitefork
sorgt dafür, dass der Letzte Prozess (der eine, wird der daemon) ist nicht eine "session leader". Nur session-Führer Erwerb einer kontrollierenden terminal, so dass diese zweite Gabel garantiert, dass der daemon nicht versehentlich erneut einen kontrollierenden terminal. Dies gilt für alle POSIX-OS.Laut "Advanced Programming in the Unix Environment" von Stephens und Rago, die zweite Gabel ist mehr eine Empfehlung, und es wird getan, um zu garantieren, dass der daemon nicht den Erwerb einer kontrollierenden terminal auf System V basierende Systeme.
Ein Grund dafür ist, dass der übergeordnete Prozess sofort wait_pid() für das Kind, und dann vergessen Sie es. Wenn dann der grand Kind stirbt, die Eltern werden ist init, und es wird wait() für es - und nehmen es aus der zombie-Zustand.
Das Ergebnis ist, dass der übergeordnete Prozess muss nicht bewusst sein, die Gabel Kinder, und es macht es auch möglich, die Gabel lang laufende Prozesse von libs etc.
Den daemon () - Aufruf hat das übergeordnete call _exit (), wenn es gelingt. Die ursprüngliche motivation haben kann, daß die Eltern zu tun, einige zusätzliche Arbeit, während das Kind daemonizing.
Kann es auch sein, beruht auf einer irrigen Annahme, dass es notwendig ist, um sicherzustellen, dass der daemon hat keine parent-Prozess und ist reparented init - aber das passiert sowieso einmal stirbt der Elternteil in der einzigen Gabel Fall.
Also vermute ich, dass es alles nur darauf an, die tradition am Ende - eine einzige Gabel ist ausreichend, solange der Elternteil stirbt in kurzer Zeit sowieso.
Eine anständige Diskussion darüber zu sein scheinen, bei http://www.developerweb.net/forum/showthread.php?t=3025
Zitieren mlampkin von dort:
Könnte es einfacher sein, zu verstehen, in dieser Art und Weise: