我的作品中有一个PHP脚本,是一个工作者;它的主要任务是检查数据库表中的新作业,如果有,则对它们进行操作。但是工作将会爆发,两者之间存在很长的差距,所以我设计了一个如下的睡眠周期:
while(true) {
if ($jobs = get_new_jobs()) {
// Act upon the jobs
} else {
// No new jobs now
sleep(30);
}
}
很好,但在某些情况下,这意味着在新工作被采取行动之前可能会有30秒的延迟。由于这是一个守护进程脚本,我想我会尝试使用pcntl_signal
钩子来捕获一个SIGUSR1信号来轻推脚本唤醒,如:
$_isAwake = true;
function user_sig($signo) {
global $_isAwake;
daemon_log("Caught SIGUSR1");
$_isAwake = true;
}
pcntl_signal(SIGUSR1, 'user_sig');
while(true) {
if ($jobs = get_new_jobs()) {
// Act upon the jobs
} else {
// No new jobs now
daemon_log("No new jobs, sleeping...");
$_isAwake = false;
$ts = time();
while(time() < $ts+30) {
sleep(1);
if ($_isAwake) break; // Did a signal happen while we were sleeping? If so, stop sleeping
}
$_isAwake = true;
}
}
我将sleep(30)
分成更小的睡眠位,以防信号没有中断{{1}}命令,认为这会导致最多一秒钟的延迟,但是在日志中文件,我看到SIGUSR1直到整个30秒过后才被捕获(可能外部sleep()
循环重置)。
我找到了pcntl_signal_dispatch
命令,但这仅适用于PHP 5.3及更高版本。如果我使用的是那个版本,我可以在while
调用之前调用该命令,但是目前看来我正在使用5.2.13。
在没有明确调用队列解析的方法的情况下,在PHP版本中解释信号队列的情况是什么?我可以在那个触发信号队列解析的睡眠循环中输入一些其他无用的命令吗?
答案 0 :(得分:2)
修正了我自己的问题:答案是“ticks”声明。作为守护程序进程启动的一部分,我完成了declare(ticks=1);
操作,但它似乎并没有转移到主脚本(因为那是在一个函数内部,在一个包含文件中?添加一个{{在declare(ticks=1)
循环之前的1}行会导致信号立即通过(即while(true)
命令导致勾号,因此在从睡眠状态唤醒后,处理信号)。