2012-04-24 37 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