我有一个 PHP 脚本(通过
php script.php
执行),它必须能够在收到 SIGTERM
信号时处理正常关闭。
为此我想使用
pcntl_signal
。一些实验表明,必须使用 pcntl_signal_dispatch
来确保信号处理程序实际上能够处理任何待处理的操作系统信号。
令我困惑的是:
pcntl_signal
的文档没有以任何方式提及pcntl_signal_dispatch
的任何用法。pcntl_signal_dispatch
的文档只是说明它将向处理程序发出信号。pcntl_signal_dispatch
,否则我的信号处理程序永远不会被拿起。调用信号处理程序时是否必须使用
pcntl_signal_dispatch
?或者是否存在 PHP 运行时自动调用信号处理程序的场景?
这是我所描述的最小可重现示例:
<?php
declare(strict_types=1);
function handleSignal(int $signo): void
{
echo "Got signal: $signo\n";
}
pcntl_signal(SIGINT, 'handleSignal');
pcntl_signal(SIGTERM, 'handleSignal');
while (true) {
// Assume that this program will receive a SIGTERM signal,
// Locally you can simply do that via using htop to kill the process.
sleep(1);
// Remove this line an the script will not get any signals:
pcntl_signal_dispatch();
}
正如对我的问题的评论,简单的答案似乎是:是的 - 如果您想在普通的 PHP 脚本中处理传入的操作系统信号,像这样调用
php your-script.php
,那么您不仅必须通过 pcntl_signal
定义信号处理程序,您还必须至少调用一次 pcntl_signal_dispatch
才能将信号转发给您的处理程序。
我想为那些主要不使用 PHP 而是使用 JS 或 Go 等类似语言的程序员添加一些上下文。使用 PHP 时,您必须牢记它的历史和主要用例。
pcntl
扩展的介绍如下:
不应在 Web 服务器环境中启用进程控制,如果在 Web 服务器环境中使用任何进程控制功能,可能会发生意外结果。
读到这里,我意识到我对
pcntl
扩展的想法是错误的。我的例外是,来自其他语言,如果我定义了一个信号处理程序,则必须在给定任何信号的情况下自动调用它。
但是从大多数 PHP 驱动的 Web 应用程序的角度思考,这有意义吗?如果您要编写一个小型 PHP 应用程序并使用某些 PHP Web 托管平台托管它,他们肯定不希望您对任何操作系统信号做出反应,因为 Web 服务器(Apache、NGINX usw.)是负责该操作的组件。