2

我在杀死有 1 个子进程的父进程时遇到问题 - 父进程正在等待子进程退出,并且只有在调用该终止处理程序之后。当未安装终止处理程序时 (pcntl_signal(SIGTERM, "kill_handler")) 脚本会立即终止。

我需要在提交终止命令以终止父进程后,终止处理函数将立即接收到信号。然后这个函数会杀死子进程。

有任何想法吗?

4

1 回答 1

2

如果您正在捕获信号,则必须在某个时候检查它们。如果您挂在阻塞waitpid()中,declare(ticks=1);请在脚本顶部使用,或WNOHANG在循环中使用 a(可能sleep),然后调用pcntl_signal_dispatch().

这不起作用:

<?php
pcntl_signal(SIGTERM, 'kill_handler');
function kill_handler($no){
        global $pid;
        posix_kill($pid,SIGTERM);
        echo 'Done killing '.$pid.PHP_EOL;
        exit;
}
$pid = pcntl_fork();
if ($pid) {
        echo 'Forked, parent is'.posix_getpid().PHP_EOL;
        pcntl_waitpid($pid,$status);
} else {
        echo 'child '.posix_getpid().PHP_EOL;
        $i = 0;
        while($i++ < 30){
                echo date('H:i:s').PHP_EOL;
                sleep(1);
        }
        echo 'done'.PHP_EOL;
}
?>

这对父母和孩子都有效:

<?php
declare(ticks=1);
//rest of previous code
?>

如果没有滴答声,这将使父级在 SIGTERM 上死去,但由于子级没有信号调度,子级会继续:

<?php
pcntl_signal(SIGTERM, 'kill_handler');
function kill_handler($no){
        global $pid;
        posix_kill($pid,SIGTERM);
        echo 'Done killing '.$pid.PHP_EOL;
        exit;
}
$pid = pcntl_fork();
if ($pid) {
        echo 'Forked, parent is'.posix_getpid().PHP_EOL;
        while(0==pcntl_waitpid($pid,$status,WNOHANG)){
                echo "nothing yet".PHP_EOL;
                pcntl_signal_dispatch();
                sleep(1);
        }
} else {
        echo 'child '.posix_getpid().PHP_EOL;
        $i = 0;
        while($i++ < 30){
                echo date('H:i:s').PHP_EOL;
                sleep(1);
        }
        echo 'done'.PHP_EOL;
}
?>

所以要么你必须调用pcntl_signal_dispatch()孩子本身,要么你pcntl_signal只需要在分叉后调用。

于 2010-07-27T20:35:48.337 回答