PHP呼び出し時にプロセスグループを終了できません。

PHP呼び出し時にプロセスグループを終了できません。

2つのゾンビを生成するスクリプトがあります。グループを終了してこれを行うことはできますがkill -- -<parent-pid>、各プロセスを手動で終了してもPHPインタプリタから呼び出すと機能しません。

スクリプトは

#!/bin/bash
sleep 1d&
sleep 1d

PHPファイルは次のように呼び出します。

<?php
exec("./spawn")
?>

シェルから直接:

$ ./spawn&
[1] 19871    
$ pstree -p 19871
spawn(19871)─┬─sleep(19872)
             └─sleep(19873)    
$ kill -- -19871    
$ pstree -p 19871
[1]+  Terminated                 ./spawn

...そしてPHPを通して:

$ php -f zomby.php &
[1] 19935    
$ pstree -p 19935
php(19935)───sh(19936)───spawn(19937)─┬─sleep(19938)
                                      └─sleep(19939)
$ kill -- -19937
bash: kill: (-19937) - No matching process found
$ kill -- -19936
bash: kill: (-19936) - No matching process found
$ kill 19939 19938 19937     
$ Terminated    
[1]+  Fertig                  php -f zomby.php

PHPの親プロセスだけを終了すると機能します。

$ php -f zomby.php &
[1] 20021

$ pstree -p 20021
php(20021)───sh(20022)───spawn(20023)─┬─sleep(20024)
                                      └─sleep(20025)
$ kill -- -20021

$ pstree -p 20021
[1]+  Terminated                 php -f zomby.php

これについて考えていますか?

ベストアンサー1

kill指定されたPIDが-1未満の場合、コマンドはプロセスIDではなくプロセスグループID(PGID)として処理します。これに関する文書は次のとおりですinfo kill

 ‘PID < -1’
      The process group whose identifier is −PID.

あなたの例をもう一度見てみると、次のようになります。

$ pstree -p 19935
php(19935)───sh(19936)───spawn(19937)─┬─sleep(19938)
                                      └─sleep(19939)

PGIDは、プロセスツリーの上部にある親プロセスのPIDです(この場合)19935。ただし、実際には1993719936プロセスグループIDではなく、IDおよびプロセスグループに属するプロセスを終了しようとしています。 PGIDはい19935

これにより、より明確に確認できますps。私のシステムで同じコマンドを実行する場合:

$ php -f ./zombie.php &
[2] 12882
$ ps  -o pid,ppid,pgid,command | grep -E '[P]GID|[1]2882'
  PID  PPID  PGID COMMAND
12882  1133 12882 php -f ./zombie.php
12883 12882 12882 /bin/bash ./spawn
12884 12883 12882 sleep 1d
12885 12883 12882 sleep 1d

上記の例では、グループのPGIDはその12882ため、そのグループのすべてのエントリを終了するにはそれを使用する必要があります。

シェルから直接コマンドを実行している場合、最上位の親プロセスはシェルスクリプトのPIDであるため、次を実行してそのツリー内のすべてのプロセスを終了できますkill -- -PID

$ ./spawn &
[3] 14213
terdon@tpad foo $ ps  -o pid,ppid,pgid,command | grep -E '[P]GID|[1]4213'
  PID  PPID  PGID COMMAND
14213  1133 14213 /bin/bash ./spawn
14214 14213 14213 sleep 1d
14215 14213 14213 sleep 1d

しかし、これはシェルスクリプトのPIDがグループのPGIDであるためです。

おすすめ記事