php 信号没有立即处理

php signal not handled right away

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

经过一些阅读,我意识到我必须在每个相关信号上添加一个处理程序才能调用 "exit;"。这样做解决了我的问题并且有效。

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

我的代码在这些括号内

declare(ticks=1)
{...}

我找不到立即治疗和不立即治疗的时间之间的任何相关性。

如有任何帮助,我们将不胜感激。

信号应该这样处理: 首先,你必须像这样制作一个信号处理程序:

function signalHandler($signo = null) {
    $pid = posix_getpid();
    switch ($signo) {
        //case SIGKILL: // you can't override SIGKILL so it is useless
        case SIGTERM:
        case SIGINT:
            // 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(表示成功或错误)

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

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

更新:

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

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