2012-04-24 33 views
3

中断按照PHP文档的pcntl_waitpcntl_wait不是SIGTERM

等待函数挂起当前进程的执行,直到孩子已经退出,或直到一个信号被发送,其作用是终止当前处理或调用信号处理功能。

然而,当我运行下面的代码,并发送SIGTERM父进程与kill -s SIGTERM [pid]信号处理程序后,才孩子退出称为(即我必须等待睡眠来完成。不应该pcntl_wait()通过SIGTERM中断

fork_test.php:

<?php 
    declare(ticks = 1); 

    function sig_handler($signo) { 
    switch ($signo) { 
     case SIGTERM: 
     echo 'SIGTERM' . PHP_EOL; 
     break; 
     default: 
    } 
    } 

    pcntl_signal(SIGTERM, 'sig_handler'); 

    $pid = pcntl_fork(); 

    if ($pid == -1) { 
    die('could not fork'); 
    } 
    else if ($pid) { 
    echo 'parent' . PHP_EOL; 

    pcntl_wait($status); 
    } 
    else { 
    echo 'child' . PHP_EOL; 
    sleep(30); 
    } 
?> 

输出(SIGTERM仅等待30秒后出现)

$ php fork_test.php 
child 
parent 
SIGTERM 

PHP版本=> 5.3.3

回答

3

您对pcntl_signal调用指定的电话应重新启动。检查docs,restart_syscalls默认为true。所以你的电话pcntl_signal不会返回,直到孩子终止。您可以拨打flush。所以PHP可以将echo的输出保存在一个缓冲区中。

因此,您所看到的行为恰恰就是您要求的行为。系统调用重新启动并且输出被缓冲。

+0

将restart_syscalls设置为false会有诀窍,尽管我并不真正了解底层发生了什么。 – ThisSuitIsBlackNot 2012-04-24 01:11:36

+0

您的'echo'只是写入缓冲区,因为您不会调用'flush'。由于您已将'restart_syscalls'设置为true,因此系统调用已重新启动,回显仍位于缓冲区中。 – 2012-04-24 01:47:42

+0

CLI中也需要flush吗? (这就是我使用的) – ThisSuitIsBlackNot 2012-04-24 03:15:44