PID 1が初期化されていることを知っています。今知りたいです。 initプロセスIDを別のプロセスIDに置き換え、PID 1に新しいプロセスを割り当てることはできますか?では、どうすればよいですか?
答え1
起動時に開始された最初のプロセスはPID 1を受け取ります。
起動時に開始された最初のプロセスには1つのタスクがあります。直接または間接的に他のすべてのプロセスを開始する必要があります。起動時にプログラムを実行するカーネルに加えてプロセスを生成する唯一の方法は、一部のプロセスがシステムコールを実行して新しいプロセスを生成することであるため、すべてのプロセスは最終的にそのプロセスの子孫です。
PID 1を持つプロセスにはアクションがあります。子プロセスの実行中にプロセスが終了すると、子プロセスの親プロセスIDが1に設定されます。子プロセスが死ぬと、PID 1はそれを収集する必要があります。つまり、システムコールを呼び出す必要がありますwait
。そうでなければゾンビサブプロセス部分は残される。
init
複数の実装を介して呼び出されるさまざまなプログラムが両方のタスクを実行します。
Linuxカーネルには、最初のプロセスとして実行される実行可能ファイルを変更するコマンドライン引数があります²。すべての実行可能ファイルを実行するために使用できますが、実行可能ファイルがinit操作を実行しないと、システムは正しく実行されません。この機能は、コンソールでシェルのみを実行し、他の操作を実行しないなど、システム回復モードに入るときに主に使用されます。
システムが正常に起動すると init が終了しないため、PID 1 を交換することはできません。 initは永久に実行するようにプログラムされているため、終了しないだけでなく(initはシステムがシャットダウンするまで実行する必要があります)、他のプロセスを終了する信号(SIGKILLなど)からも特別な保護を受けます。
LinuxではPID名前空間独自のプロセスIDセットを使用して、サブシステムの機能を定義できます。名前空間のPIDプロセスは、名前空間の内側と外側から見たときに異なるPIDを持ちます。名前空間の最初のプロセスは、名前空間からPID 1を取得します。名前空間の外にはPID 1はありません(initがジョブの完了を妨げるため、initが実行しない新しいPID名前空間入力を選択しない限り)。
1これは完全に正確ではありません。一部のカーネルにはプロセスを開始する別の方法があります。たとえば、modprobe
Linux は特定の状況で特定のハードウェアが見つかると起動します。しかし、initの子孫はほとんどのプロセスを占めています。
²前前後ファイルシステムの初期化または初期化プログラム。
答え2
Gillesが指摘したように、initはいくつかの点で特別です。 initが終了すると、ほとんどの場合カーネルパニックが発生するため、評判の良いinit作成者であれば、このような状況を避けるために多くの努力を払うことになります。一方、ゾンビプロセスを処理することを除いて、他のプログラムと非常によく似ており、実際にはどのプログラムでもinitとして使用できます。 catはうまく機能しますが、完全には役に立ちません。 initがこれを行うことができる非常に簡単な方法の1つは、execlve(execと友達)を呼び出して、同じpidを使用してあるプログラムを別のプログラムに置き換えることです。たとえば、初期ルートディスクは実行するドライブをマウントし、それを使用して物理initを実行します。