PHP <5.3.0 守护程序脚本何时接收信号?

发布于 2024-08-31 03:54:00 字数 1499 浏览 4 评论 0 原文

我正在开发一个 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 版本中的信号队列会被解释而无法显式调用队列解析?我可以在该睡眠循环中放入其他一些无用的命令来触发其中的信号队列解析吗?

I've got a PHP script in the works that is a job worker; its main task is to check a database table for new jobs, and if there are any, to act on them. But jobs will be coming in in bursts, with long gaps in between, so I devised a sleep cycle like:

while(true) {
  if ($jobs = get_new_jobs()) {
    // Act upon the jobs
  } else {
    // No new jobs now
    sleep(30);
  }
}

Good, but in some cases that means there might be a 30 second lag before a new job is acted upon. Since this is a daemon script, I figured I'd try the pcntl_signal hook to catch a SIGUSR1 signal to nudge the script to wake up, like:

$_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;
  }
}

I broke the sleep(30) up into smaller sleep bits, in case a signal doesn't interrupt a sleep() command, thinking that this would cause at most a one-second delay, but in the log file, I'm seeing that the SIGUSR1 isn't being caught until after the full 30 seconds has passed (and maybe the outer while loop resets).

I found the pcntl_signal_dispatch command, but that's only for PHP 5.3 and higher. If I were using that version, I could stick a call to that command before the if ($_isAwake) call, but as it currently stands I'm on 5.2.13.

On what sort of situations is the signals queue interpreted in PHP versions without the means to explicitly call the queue parsing? Could I put in some other useless command in that sleep loop that would trigger a signal queue parse within there?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

过期情话 2024-09-07 03:54:00

解决了我自己的问题:答案是“

Fixed my own problem: The answer is the "ticks" declaration. I had, as part of the Daemon process startup done the declare(ticks=1); action, but it wasn't seeming to carry over to the main script (since that was inside a function, in an include file?. Adding a declare(ticks=1) line before the while(true) loop causes signals to come through immediately (i.e. the sleep(1) command causes a tick, so after waking up from sleep, signals are processed).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文