DAEMON(3)はどのように動作するか?バックグラウンドプロセスとして実行する

DAEMON(3)はどのように動作するか?バックグラウンドプロセスとして実行する

プロセスを端末から切り離す手順は何ですか?そのためには、次のマニュアルページを見つけました。daemon()説明文には、

nochdir がゼロの場合、daemon() はプロセスの現在の作業ディレクトリをルート ディレクトリ ("/") に変更します。それ以外の場合、現在の作業ディレクトリは変更されません。

noclose がゼロの場合、daemon() は標準入力、標準出力、および標準エラーを /dev/null にリダイレクトします。それ以外の場合、これらのファイル記述子には変更は加えられません。

実は、私はPythonコードをデーモンとして実行しようとしていました。tcollectorコードを見つけましたここそのコードでも、の説明と同じ手順を実行していますdaemon()。そこで私の質問は、なぜこれらの手順を実行する必要があるのか​​ということです(daemonize()tcollector)のように

なぜdirを に変更し/umaskを に変更し022てからos.setsid()などを呼び出すのでしょうか。

答え1

実際にはあなたが引用したものよりも多くの情報がありますが、マニュアル ページはより明確にできると思います。

nochdirがゼロの場合、daemon()プロセスの現在の作業ディレクトリをルートディレクトリに変更します(/

ここでの前提は、プログラムが管理者のコマンド ラインから起動され、その時点で管理者が行っていた作業からデーモンを切り離すことです。作業ディレクトリを に変更すると、/デーモンがマウント ポイントをビジー状態に維持するのを防ぎます。たとえば、作業ディレクトリが で/home/admin、しばらくしてからアンマウントしたい場合/home、デーモンはそれを阻止します。

noclose がゼロの場合、daemon()標準入力、標準出力、標準エラーを/dev/null;にリダイレクトします。

これは、デーモンがユーザーの端末に不要なエラー メッセージなどを書き込んでユーザーを混乱させることを防ぐためです。デーモンが行うべきことは、おそらく、何らかの (設定された) ログ ファイルを開いて、外部に伝えたいことをそこに書き込むことです。

(この関数はフォークし、fork(2) が成功すると親は _exit(2) を呼び出すので、それ以降のエラーは子にのみ表示されます。)

繰り返しになりますが、管理者のシェルセッションから切り離すには、メインプログラムはすぐに戻り、他の部分はバックグラウンドに残るため、プログラムをバックグラウンドで起動するように明示的に要求する必要はありません (例./daemon &)

さて、マニュアル ページでは明示的には説明されていませんが、ここでは (バグの下) 次のように示唆されています。

この関数の GNU C ライブラリ実装は BSD から取得されており、結果として得られるデーモン プロセスがセッション リーダーにならないようにするために必要なダブルフォーク技術 (fork(2)、setsid(2)、fork(2) など) は採用されていません。代わりに、結果として得られるデーモンはセッション リーダーになります。

daemon()また、setsid()セッションから解放される制御端末、したがって端末から送信されるシグナルから。しかし、引用文にあるように、端末デバイスを開いた場合、誤ってそれを制御端末として取得する可能性があります。これを回避するため、一部のプログラムは を呼び出しfork()、次にsetsid()子から を呼び出し、次に再度フォークして両方の親を終了し、結果として得られるプロセスがセッション リーダーにならないようにし (中間のプロセスはセッション リーダーです/でした)、制御端末を取得できないようにします。参照されている Python プログラムはまさにそれを行います。

の変更はumaskデーモン化とはあまり関係ないようです。おそらく、そのプログラムには特別な必要性があるのでしょう。

関連情報