Ubuntu Linux 16.04デーモン機能はデュアルフォークを実行しますか?では、なぜデュアルフォークが必要なのですか?
[2016年5月30日午前8時11分修正]これは私がこの質問で述べたデーモン機能の公式Linux Foundationソースコードです。
92 int daemon(int nochdir, int noclose)
93 {
94 int status = 0;
95
96 openlog("daemonize", LOG_PID, LOG_DAEMON);
97
98 /* Fork once to go into the background. */
99 if((status = do_fork()) < 0 )
100 ;
101
102 /* Create new session */
103 else if(setsid() < 0) /* shouldn't fail */
104 status = -1;
105
106 /* Fork again to ensure that daemon never reacquires a control terminal. */
107 else if((status = do_fork()) < 0 )
108 ;
109
110 else
111 {
112 /* clear any inherited umask(2) value */
113
114 umask(0);
115
116 /* We're there. */
117
118 if(! nochdir)
119 {
120 /* Go to a neutral corner. */
121 chdir("/");
122 }
123
124 if(! noclose)
125 redirect_fds();
126 }
127
128 return status;
129 }
実行パスに応じて1回または2回分岐します。
答え1
daemon(3)
ソースコードが#1にある可能性があるライブラリ呼び出しを参照しているようです。https://github.com/lattera/glibc/blob/master/misc/daemon.cまたは#2でhttps://github.com/bmc/daemonize/blob/master/daemon.c。どちらのバージョンも今回のシングルに録音されました。マニュアルページ。
#1のソースコードはを示していますfork(2)
。 #2のソースコードはdoubleを示していますfork(2)
。表面的には、これら2つの関数は同じ結果を与えるように見えますが、方法は異なります。
二重に扱うことはfork(2)
必ずしも必要ではありません。これは質問の第2部の推進力に反して、もはや必要ではないと思います。しかし、このアプローチの根本的な理由は、フォークされたプロセスがどの状況でも制御端末を再取得できないことを保証することです。最新のコードでは、サブプロセスを新しいセッションリーダーに設定してこの問題を解決します。
このサイトと同様の質問をする他のStackOverflowサイトに他の関連質問があります。これは一つ。
答え2
次のようにフォークglibc
のみdaemon()
ソースコード。
まず、外部から直接参照するのではなく、カーネルのソースコードを見てみましょう。
デュアルフォークの使用は、実際の呼び出しデーモンの実装に依存し、デーモンが通常のセッションで開始されないため、ほとんどのデザインでは必要ありません。
カーネルのソースコードが示すように、2回分岐すると、親プロセスが最初のプロセスにあったため、プロセスは親から完全に分離されますfork()
。 2番目のプロセスを呼び出しfork()
て親を殺すと、プロセスが割り当てられます。これも完全に削除されます。 (親プロセスID)1
にPPID
割り当てられたTTY。