PHPの子プロセスとシグナルPart 1


取る
  • PHP :マルチスレッドのネイティブサポート
  • 代替案pcntl_fork() 子プロセスを作る
  • 子プロセスを復帰するpcntl_wait() and pcntl_signal()
  • pcntl_wait() 子プロセスの状態を扱うことができます.親プロセスの状態に対する反応は全くありません.
  • pcntl_wait() 子プロセスで呼び出された場合、何の影響もない
  • pcntl_signal() 親プロセスをkillした場合、子プロセスのシグナルハンドラは動作しません.中pcntl_wait() シグナル用の働き.私が子供を殺すならばpcntl_wait() 親で検出します.

  • 子プロセスを作成するpcntl_fork()
    if ($pid = pcntl_fork()) {
        $parent = getmypid();
        echo "parent: $parent\n";
    } else {
        $childPid = getmypid();
        echo "child pid: $childPid\n";
    }
    
    (上記の例は、ジョージSchrossnagleによる高度なPHPプログラミングからです).
    ポイントpcntl_fork() 呼び出されると、子プロセスが作成されます.親プロセスではpcntl_fork() 子プロセスのpidを返し、一方子プロセスでは0を返す.

    子プロセスを復帰するpcntl_wait() and pcntl_signal() pcntl_wait() を待つか、forkした子の状態を返す.呼び出し元プロセスは、子プロセスの終了までの実行を中断するよう指示する.二つの注意点:
  • それは親プロセスの状態のための完全な反応の子プロセスの状態を処理することができます.
  • それは子プロセスで呼ばれるとき、何の影響もありません
    More detail here .
  • Detailed example : 子供たちの後の掃除pcntl_signal シグナルハンドラをインストールします.シグナルはプロセスへの指示である.例えば、コマンドを実行するときkill プロセスを終了するには、システムは割り込みシグナルsigintを送出する.シグナルハンドラを使用すると、プロセスに対処するための関数を定義できます.
    子プロセスを再利用する方法を次の例に示します.
    pcntl_async_signals(true);
    
    pcntl_signal(SIGTERM, function ($signal, $status) {
        echo "inside pcntl_signal\n";
        $pid = pcntl_wait($processStatus, WUNTRACED);
    //    $pid = pcntl_wait($processStatus, WNOHANG);
    
        if (pcntl_wifexited($processStatus)) {
            $code = pcntl_wexitstatus($processStatus);
            print "pid $pid returned exit code: $code\n ";
        } else {
            print "$pid was unnaturally terminated\n ";
        }
    //    print_r($processStatus);
    //    echo "\n";
    //    echo "signal: $signal\n";
    //    print_r($status);
    });
    if ($pid = pcntl_fork()) {
        $parent = getmypid();
        echo "parent: $parent\n";
    
        sleep(60);
    } else {
        $childPid = getmypid();
        echo "child pid: $childPid\n";
    
        sleep(60);
    }
    
    上記のスクリプトを実行し、プロセスPIDの出力に従って、最初の使用kill 親プロセスをkillし、子プロセスをkillするコマンド.出力は以下のようになります:
    parent: <parent pid>
    child pid: <child pid>
    inside pcntl_signal  //shows when parent gets killed
    inside pcntl_signal //shows when child gets killed
    pid -1 returned exit code: 0
    pid <child pid> returned exit code: 0
    
    どうしたの?まずスクリプトを実行し、親プロセスと子プロセスを作成します.それから、親プロセスを殺します.そして、それはSIGINTシグナルを送ります.それで、我々は最初の「内部のpcntlchen信号」を得ます、そしてpcntl_wait forkプロセスのためだけに動作するので、親プロセスのシグナルを処理できません.パラメータpcntl_wait は' ununtraced 'であり、子から有効なシグナルが得られるまで待つでしょう.
    それから子プロセスをkillしますが、もう一度シグナルハンドラを呼び出します.しかし、なぜ' PID *返された出口コード*'の2行がありますか?だってpcntl_wait 親が働いている」pid - 1は終了コードを返します.pcntl_wait() 子プロセスで呼び出された場合、何の影響もない.The pcntl_wait() 親プロセスで子プロセスの終了を検出します.
    それで、我々が最初に子供を殺して、次に、親を殺すならば、何が起こりますか?