php信号没有立即处理

时间:2015-05-05 15:29:34

标签: php signals pcntl

我有一个用PHP编写的软件可以运行很长时间,它是通过命令行(而不是Web应用程序)进行的。我想确保在软件退出时调用一个函数,包括通过ctrl + c杀死时。当被信号杀死时,不会调用关闭函数(通过register_shutdown_fucntion()注册的析构函数和函数)。

经过一些阅读,我意识到我必须在每个相关信号上添加一个处理程序,只是为了调用"退出;"。这样做解决了我的问题并起作用。

我的问题是,在某些情况下,信号不会立即处理。它可能需要几秒钟,几分钟,在某些情况下,根本不会处理。就像从未到过处理程序代码一样。我真的不知道从哪里开始调试。我已经尝试过其他信号(sigkill,sighup等),同样的行为。

我的代码正在使用这些括号

declare(ticks=1)
{...}

我无法立即发现它与不受影响的时间之间存在任何关联。

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:0)

信号应该以这种方式处理: 首先,你必须制作一个这样的信号处理程序:

function signalHandler($signo = null) {
    $pid = posix_getpid();
    switch ($signo) {
        //case SIGKILL:
        case SIGTERM:
        case SIGINT:
        case SIGKILL:
            // unexpected shut down
            exit(3);
            break;
        case SIGCHLD:
        case SIGHUP:
            // just ignore it
            break;
        case 10:
            // user signal 1 received. Process exited normally
            exit(0);
            break;
        case 12:
            // user signal 2 received. Precess exited with a catched error
            exit(3);
            break;
        default:
            // ignore other signals
    }
}

然后,在你的主要过程中,你必须告诉PCNTL你正在使用这个处理程序:

    pcntl_signal(SIGTERM, "signalHandler");
    pcntl_signal(SIGINT, "signalHandler");
//  pcntl_signal(SIGKILL, "signalHandler"); // you can't override SIGKILL so it is useless
    pcntl_signal(SIGCHLD, "signalHandler");
    pcntl_signal(SIGHUP, "signalHandler");
    pcntl_signal(10, "signalHandler");
    pcntl_signal(12, "signalHandler");

我正在使用它,似乎适用于200个进程,8个进程同时运行,每个进程运行10秒。

此处,当进程退出时,他使用posix_kill($pid, 10)发送信号10或12(表示成功或错误)

答案 1 :(得分:0)

我认为这里的问题是,也许您调用了一个包含循环的函数,而循环的每次迭代都需要花费大量时间(例如,从数据库中获取数据)。在这种情况下,当您的程序收到停止信号时,它会将此信号添加到堆栈中,等待,直到从数据库中获取数据,然后调用信号处理函数。

我也在寻找一种方法来立即调用信号处理函数。也许 PHP 没有这个选项。

更新:

我想我找到了解决方案。尝试将 false 作为第三个参数传递给函数 pcntl_signal(),如下所示:

pcntl_signal(SIGINT, function () {
    echo 'Do something here.';
}, false);