私はいつも、initプロセスがすべてのプロセスの祖先であることを学びました。プロセス2のPPIDが0になっているのはなぜですか?
$ ps -ef | head -n 3
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 May14 ? 00:00:01 /sbin/init
root 2 0 0 May14 ? 00:00:00 [kthreadd]
まず、「祖先」は「親」と同じではありません。祖先は親の親の…親の親になることができ、カーネルは1つのレベルのみを追跡します。ただし、プロセスが停止すると、その子はinitによって採用されるため、通常のシステムでは、親が1であるプロセスが多数表示されます。
最近のLinuxシステムには、カーネルコードを実行するいくつかのプロセスがありますが、スケジューリングに関してはユーザープロセスとして管理されます。 (カーネルコードを実行しているため、通常のメモリ管理ルールに従いません。)これらのプロセスはすべてkthreadd
によって生成されます(カーネルスレッドの初期値です)。それらは、親プロセスID(2)によって、または通常、ps
が角括弧の間に名前を付けてそれらをリストするという事実、または/proc/2/exe
(通常はへのシンボリックリンク)によって認識できます。プロセス実行可能ファイル)を読み取ることができません。
プロセス1(init
)および2(kthreadd
)は、ブート時にカーネルによって直接作成されるため、親はありません。値0は、それを示すためにppidフィールドで使用されます。ここで「カーネル自体」を意味する0と考えてください。
Linuxには、特定の状況で sysctlパラメータ を介して場所が示されるユーザープロセスをカーネルが開始するためのいくつかの機能もあります。たとえば、カーネルは、kernel.modprobe
sysctl値でプログラムを呼び出すことにより、モジュールのロードイベント(新しいハードウェアが検出されたとき、または一部のネットワークプロトコルが最初に使用されたときなど)をトリガーできます。プログラムがコアをダンプすると、カーネルは kernel.core_pattern
で示されるプログラムを呼び出します(存在する場合)。