【问题标题】:PHP - child process blocking SIGTERM for parentPHP - 子进程阻止父进程的 SIGTERM
【发布时间】:2011-03-17 10:18:36
【问题描述】:

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

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

有什么想法吗?

【问题讨论】:

    标签: php process parent-child kill terminate


    【解决方案1】:

    如果您要捕获信号,则必须在某个时候检查它们。如果你挂在一个阻塞的waitpid(),在你的脚本顶部使用declare(ticks=1);,或者在循环中使用WNOHANG(可能是sleeping),然后调用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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-22
      • 2013-07-05
      • 2010-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多