我有一个用PHP编写的软件可以运行很长时间,它是通过命令行(而不是Web应用程序)进行的。我想确保在软件退出时调用一个函数,包括通过ctrl + c杀死时。当被信号杀死时,不会调用关闭函数(通过register_shutdown_fucntion()注册的析构函数和函数)。
经过一些阅读,我意识到我必须在每个相关信号上添加一个处理程序,只是为了调用"退出;"。这样做解决了我的问题并起作用。
我的问题是,在某些情况下,信号不会立即处理。它可能需要几秒钟,几分钟,在某些情况下,根本不会处理。就像从未到过处理程序代码一样。我真的不知道从哪里开始调试。我已经尝试过其他信号(sigkill,sighup等),同样的行为。
我的代码正在使用这些括号
declare(ticks=1)
{...}
我无法立即发现它与不受影响的时间之间存在任何关联。
任何帮助都将不胜感激。
答案 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);