PHP中のゾンビプロセス、孤児プロセスの詳細

3831 ワード

ゾンビプロセス
サブプロセスの実行が終了すると、親プロセスは引き続き実行されますが、親プロセスはサブプロセスを回収せず、サブプロセスが占有するリソースを解放します.このとき、サブプロセスはゾンビプロセスになります.
Unixプロセス管理では、新しく開いたサブプロセスの実行が終了すると、親プロセスはSIGCHLD信号を受信し、サブプロセスは一時的にゾンビプロセスとなり、親プロセスの処理を待つ.親プロセスが処理されない場合、プロセスは常に存在し、システムプロセステーブルのアイテムを占有し、ゾンビプロセスになります.ゾンビプロセスが多すぎると、システムに使用可能なプロセステーブル項目がないため、他のアプリケーションを実行できません.
 0) {
    echo "     ,id " . getmypid() . ",    pid {$pid}" . PHP_EOL;
    pcntl_async_signals(true);
    pcntl_signal(SIGCHLD, function () {
        echo '      ,     ' . PHP_EOL;
    });
    while (1) {  //         
        sleep(1);
    }
} elseif($pid==0) {
    echo "     ,  pid ". getmypid() ."
"; }else{ echo " ,
"; }

psを使用してゾンビプロセスを表示するには:
ps -A -ostat,ppid,pid,cmd | grep -e '^[Zz]'

端末は次のように出力します.
Z+     7136   7137 [php] 

メインプロセスが終了すると、サブプロセスはinitに引き継がれ、処理されます.
pcntl_の使用waitゾンビ回収プロセス:
 0) {  //     
    pcntl_wait($status);  //               
    echo time() . PHP_EOL;
} elseif($pid==0) {
    sleep(3);
    echo "     ,  pid ". getmypid() ."
"; exit(); }else{ die(" ,
"); }
1589874657
     ,  pid 16140
1589874660

pcntl_wait($status); デフォルトはブロック回収サブプロセスで、2番目のパラメータがWNOHANGである非ブロック回収サブプロセスを設定できます.コードは引き続き実行され、サブプロセスが終了すると自動的に回収されます.
複数のサブプロセスにはpcntlが1つしか必要ありません.waitで回収できます.
親プロセスで、SIGCHLDのhandlerを構成して回収します.
 0) {  //     
    sleep(10);
    echo time() . PHP_EOL;
} elseif($pid==0) {
    sleep(3);
    echo "     ,  pid ". getmypid() ."
"; exit; }else{ die(" ,
"); }
1589874039
     ,  pid 12875
SIGCHLD
1589874040

サブプロセス終了信号を無視し、initによって回収する:
 0) {  //     
    sleep(10);
    echo time() . PHP_EOL;
} elseif($pid==0) {
    sleep(3);
    echo "     ,  pid ". getmypid() ."
"; exit; } else { die(" ,
"); }
1589874331
1589874331
     ,  pid 14493

孤児プロセス
孤児プロセスとは、親プロセスの実行が完了した後も、終了した後も実行を継続するプロセスの一種です.これらの孤児プロセスはinitプロセスによって養子縁組され、initプロセスによって回収作業が完了します.
孤児プロセスには何の危害もなく、自分のコードロジックに注意すればいい.
 0) {
    echo "     ,       " . PHP_EOL;
    exit();     //               
} else {
    //        
    $i = 10;
    while($i) {
        echo $i;
        $i--;
        sleep(1);
    }
}
     ,       
1111111111...

孤児プロセスとゾンビプロセスの違い
ゾンビプロセス:親プロセスがwait()またはwaitpid()を呼び出していない場合にサブプロセスが終了します.このサブプロセスはゾンビプロセスです.いずれのサブプロセスも、終了後、すぐに消えるのではなく、ゾンビプロセスと呼ばれるデータ構造を残して、親プロセスの処理を待つ.これは、各サブプロセスが終了するときに通過するフェーズです.サブプロセスが終了した後、親プロセスが処理に間に合わなかった場合、サブプロセスは解放されず、そのプロセス番号はずっと占有されますが、システムが使用できるプロセス番号は限られています.ゾンビプロセスが大量に発生すると、使用可能なプロセス番号がないため、システムは新しいプロセスを生成できません.これはゾンビプロセスの危害であり、避けるべきである.
孤児プロセス:親プロセスが終了し、その1つ以上のサブプロセスが実行されている場合、それらのサブプロセスは孤児プロセスになります.孤児プロセスはinitプロセスによって養子縁組され、initプロセスによって回収作業が完了します.孤児プロセスが現れるたびに、カーネルは孤児プロセスの親プロセスをinitに設定し、initプロセスは終了したサブプロセスを循環的にwait()します.これにより、孤児プロセスがライフサイクルを終了すると、initプロセスは回収作業を行います.そのため、孤児のプロセスには危害はありません.