web-dev-qa-db-ja.com

Linuxデーモン化

Linuxデーモンを書いています。 2つの方法を見つけました。

  1. fork()を呼び出し、sidを設定して、プロセスをデーモン化します。
  2. &を使用してプログラムを実行します。

それを行う正しい方法はどれですか?

45
Poorna

から http://www.steve.org.uk/Reference/Unix/faq_2.html#SEC16

デーモンになる手順は次のとおりです。

  1. fork()により、親が終了できるようになります。これにより、コマンドラインまたはプログラムを呼び出すシェルに制御が戻ります。このプロセスは、新しいプロセスがプロセスグループリーダーではないことが保証されるために必要です。プロセスグループリーダーの場合、次のステップであるsetsid()は失敗します。
  2. プロセスグループおよびセッショングループリーダーになるためのsetsid()。制御端末はセッションに関連付けられており、この新しいセッションはまだ制御端末を取得していないため、プロセスには制御端末がありません。これはデーモンにとって良いことです。
  3. 再びfork()すると、親(セッショングループリーダー)が終了できます。これは、非セッショングループリーダーとして、制御端末を回復できないことを意味します。
  4. chdir( "/")を使用して、プロセスが使用中のディレクトリを保持しないようにします。これを行わないと、現在のディレクトリであるため、管理者がファイルシステムをアンマウントできなくなる可能性があります。 [同様に、デーモンの動作にとって重要なファイルを含む任意のディレクトリに変更できます。]
  5. umask(0)を使用すると、作成するすべての権限を完全に制御できます。継承したumaskがわからない。 [この手順はオプションです]
  6. close()fds 0、1、および2。これにより、親プロセスから継承した標準の入力、出力、およびエラーが解放されます。これらのfdsのリダイレクト先を知る方法はありません。多くのデーモンはsysconf()を使用して_SC_OPEN_MAXの制限を決定します。 _SC_OPEN_MAXは、開いているファイル/プロセスの最大数を示します。その後、ループ内で、デーモンは可能なすべてのファイル記述子を閉じることができます。これを行う必要があるかどうかを決定する必要があります。開いているファイル記述子があるかもしれないと思うなら、それらを閉じる必要があります。なぜなら、同時ファイル記述子の数には制限があるからです。
  7. Stdin、stdout、stderrの新しいオープン記述子を確立します。使用する予定がない場合でも、開いたままにすることをお勧めします。これらの正確な取り扱いは好みの問題です。たとえば、ログファイルがある場合、stdoutまたはstderrとしてそれを開き、stdinとして '/ dev/null'を開きます。または、「/ dev/console」をstderrおよび/またはstdoutとして、「/ dev/null」をstdinとして、または特定のデーモンにとって意味のある他の組み合わせを開くことができます。

さらに良いのは、利用可能であれば daemon() 関数を呼び出すだけです。

77
nos

プログラムをデーモンとしてまったく作成しないことをお勧めします。ファイル記述子、現在のディレクトリ、プロセスグループなどを指定してフォアグラウンドで実行します。

このプログラムをデーモンとして実行する場合は、start-stop-daemon(8)、init(8)、runsv(runitから)、upstart、systemdなどを使用して、プロセスをデーモンとして起動します。つまり、ユーザーにプログラムの実行方法を決定させ、デーモンとして実行する必要があることを強制しないでください。

29
camh

daemon(3) (from unistd.h)。

Daemon()関数は、制御端末から自身を切り離し、システムデーモンとしてバックグラウンドで実行したいプログラム用です。 ...

12
jkramer

最初。 2番目はデーモン化されていませんが、バックグラウンドで実行されています。デーモン化されたプログラムは、独自のセッションおよびプロセスグループ上にある必要があり、notに制御端末が必要です。

5
ninjalj

どの言語を使用していますか?一部の言語には、デーモン化を容易にするヘルパーメソッドがあります。たとえば、Rubyには daemons パッケージがあります。

2
bta

実際にデーモンを作成するには、フォークを2倍にしなければなりません。

&を指定してプログラムを実行すると、シェルはプログラムをバックグラウンドで実行しますが、デーモンにはなりません。デーモンには親としてinit(pid 1)があるため、ダブルフォークが必要です。

したがって、プログラムがデーモンである場合、物事を行う素敵な方法は、この問題を自分で処理することです(他の方法があります。 here も参照)。 start-stop-daemonプログラムを使用することもできます。

1
Unknown