Linuxデーモンプログラミング規則

3404 ワード

このblogを書く理由は、仕事でよくデーモン(daemon)を書く必要があるからです.
私たちがデーモンプロセスを作成する方法は、デーモンプロセスのプログラミングに従わない簡単で乱暴なことが多い.
デーモンプロセスを作成する一般的な方法は、次のとおりです.
pid = fork();
if (pid < 0) {  // fork failed
    printf("fork error
"); exit(1); } else if (pid > 0) { // parent process return; } else { // child process // daemon begin to execute }
上にデーモンプロセスを作成する方法は、実質的な機能も実現できるが、規範化されていない.上記の作成方法では、不要なインタラクションを引き起こす可能性があります.
したがって,標準デーモンの作成方法,すなわちデーモンのプログラミングルールを明らかにする必要がある.
1.デーモンプロセスとは?
デーモンプロセス(daemon)は、バックグラウンドで実行される特殊なプロセスです.制御端末とは独立して、あるタスクを周期的に実行したり、発生したイベントの処理を待ったりします.
2.デーモンプロセスの特徴?
デーモンプロセスの最も重要な特性はバックグラウンドで実行されます.この点、DOSでの常駐メモリプログラムTSRはこれに似ている.
次に、デーモンプロセスは、実行前の環境から分離する必要があります.これらの環境には、閉じていないファイル記述子、制御端末、セッションおよびプロセスグループ、作業ディレクトリ、およびファイル作成マスクなどが含まれます.
これらの環境は、通常、保護プロセスが実行する親プロセス(特にshell)から継承されます.
最後に、デーモンプロセスの起動方法には特別な点があります.Linuxシステムの起動時に起動スクリプト/etc/rcから起動できます.dで起動し、ジョブプランニングプロセスcrondで起動してもよいし、ユーザ端末(通常shell)で実行してもよい.
要するに,これらの特殊性を除いて,デーモンプロセスは通常のプロセスとほとんど変わらない.したがって,デーモンプロセスを記述することは,実際には1つの一般的なプロセスを上述したデーモンプロセスの特性に従ってデーモンプロセスに改造することである.
3.プロセスを守るプログラミングルール?
デーモンの作成には、不要なインタラクションを防止するための基本的なルールが必要です.
(1)まずumaskを呼び出し,ファイル権限マスクをリセットする.
ファイル権限マスクとは、ファイル権限の対応するビットをブロックすることです.たとえば、ファイル権限マスクが050であると、ファイルグループ所有者の読み取り可能および実行可能な権限がブロックされます.fork関数を使用して新しいサブプロセスが親プロセスのファイル権限マスクを継承するため、このサブプロセスがファイルを使用するのに多くのトラブルが発生します.したがって、ファイル権限マスクを0に設定すると、デーモンプロセスの柔軟性が大幅に向上します.ファイル権限マスクを設定する関数はumaskです.ここで、通常の使用方法はumask(0)である.
(2)forkを呼び出し、親プロセスを終了する(exit).
これは、デーモンプロセスを作成する最初のステップです.デーモンプロセスは制御端末から離れているため,最初のステップが完了するとシェル端末にプログラムが実行されたという仮象をもたらす.その後のすべての作業はサブプロセスで完了し,ユーザはShell端末で他の命令を実行することができ,制御端末からの離脱を形式的に行うことができる.Linuxでは、親プロセスがサブプロセスより先に終了すると、サブプロセスが孤児プロセスになり、システムが孤児プロセスを発見するたびに、自動的に1番プロセス(init)によって養子縁組されます.これにより、元のサブプロセスはinitプロセスのサブプロセスになります.
(3)setsidを呼び出して新しいセッションを作成する.
このステップは、実装は非常に簡単ですが、その意味は非常に重要です.
ここではシステム関数setsidを使用します.setsidを具体的に説明する前に、まず2つの概念を理解します.プロセスグループとセッション期間プロセスグループ:1つ以上のプロセスの集合です.プロセスグループには、プロセスグループIDがあり、一意に識別されます.プロセス番号(PID)に加えて、プロセスグループIDもプロセスの必須属性です.各プロセスグループには、プロセスグループIDに等しいプロセス番号を持つグループ長プロセスがあります.プロセスグループIDは、チーム長プロセスの終了によって影響を受けない.≪セッション期間|Session Period|emdw≫:セッション期間は、1つ以上のプロセス・グループの集合です.通常、1つのセッションはユーザーとログインし始め、ユーザーが終了するまで終了します.この間、ユーザーが実行したすべてのプロセスはこのセッション期間に属します.
次に、setsidに関する内容を具体的に説明します.setsid関数の役割:setsid関数は、新しいセッションを作成し、そのセッショングループのグループ長を担当するために使用されます.setsidを呼び出すには、プロセスを元のセッションの制御から解放し、プロセスを元のプロセスグループの制御から解放し、プロセスを元の制御端末の制御から解放する3つの役割があります.
では、デーモンプロセスを作成するときにsetsid関数を呼び出すのはなぜですか?デーモンの作成の最初のステップがfork関数を呼び出してサブプロセスを作成したため、親プロセスを終了します.fork関数が呼び出されると、サブプロセスは親プロセスのセッション期間、プロセスグループ、制御端末などを全面的にコピーするためです.親プロセスは終了したが、セッション期間、プロセスグループ、制御端末などは変更されていないため、本当の意味での独立ではなく、setsid関数はプロセスを完全に独立させ、他のプロセスの制御から抜け出すことができる.
(4)現在の作業ディレクトリをルートディレクトリに変更する.
親プロセスから継承された現在の作業ディレクトリは、アセンブリファイルシステムにある可能性があります.デーモンプロセスは、システムが再起動される前から存在する可能性がありますので、デーモンプロセスの現在の作業ディレクトリ
1つのアセンブリファイルシステムでは、ファイルシステムは分解できません.これはファイルシステムをアセンブリする本来の意味と一致しません.
(5)不要なファイル記述子を閉じる.
fork関数で新しいサブプロセスは、親プロセスから開いているファイルを継承します.これらの開いているファイルは、デーモンプロセスによって読み書きされない場合がありますが、システムリソースが消費され、ファイルシステムが取り外すことができない可能性があります. 
(6)一部のデーモンは/dev/null*を開き、ファイル記述子0、1、2を持つ.
デーモンプロセスは端末装置に関連付けられていないため,端末装置に出力を表示することができず,インタラクティブユーザから入力を受信する場所もない.
*クラスUnixシステムでは、/dev/null、または空のデバイスと呼ばれ、特殊なデバイスファイルであり、その中に書き込まれたデータをすべて破棄します(ただし、書き込み操作に成功したことを報告します)、それを読み取るとすぐにEOFが得られます.