我在杀死有 1 个子进程的父进程时遇到问题 - 父进程正在等待子进程退出,并且只有在调用该终止处理程序之后。当未安装终止处理程序时 (pcntl_signal(SIGTERM, "kill_handler")) 脚本会立即终止。
我需要在提交终止命令以终止父进程后,终止处理函数将立即接收到信号。然后这个函数会杀死子进程。
有任何想法吗?
我在杀死有 1 个子进程的父进程时遇到问题 - 父进程正在等待子进程退出,并且只有在调用该终止处理程序之后。当未安装终止处理程序时 (pcntl_signal(SIGTERM, "kill_handler")) 脚本会立即终止。
我需要在提交终止命令以终止父进程后,终止处理函数将立即接收到信号。然后这个函数会杀死子进程。
有任何想法吗?
如果您正在捕获信号,则必须在某个时候检查它们。如果您挂在阻塞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
只需要在分叉后调用。