【发布时间】:2010-04-29 18:42:10
【问题描述】:
我正在开发一个 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) 分解为更小的睡眠位,以防信号不会中断sleep() 命令,我认为这最多会导致一秒钟的延迟,但在日志文件中,我'我看到 SIGUSR1 直到整整 30 秒过去后才被捕获(并且可能外部 while 循环重置)。
我找到了pcntl_signal_dispatch 命令,但这仅适用于 PHP 5.3 及更高版本。如果我使用的是那个版本,我可以在if ($_isAwake) 调用之前对该命令进行调用,但就目前而言,我使用的是 5.2.13。
在哪些情况下,信号队列在 PHP 版本中被解释而没有显式调用队列解析的方法?我可以在那个睡眠循环中放入一些其他无用的命令,以触发其中的信号队列解析吗?
【问题讨论】: