【问题标题】:When does a PHP <5.3.0 daemon script receive signals?PHP <5.3.0 守护程序脚本何时接收信号?
【发布时间】: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 版本中被解释而没有显式调用队列解析的方法?我可以在那个睡眠循环中放入一些其他无用的命令,以触发其中的信号队列解析吗?

【问题讨论】:

    标签: php daemon


    【解决方案1】:

    解决了我自己的问题:答案是“ticks”声明。作为守护进程启动的一部分,我完成了declare(ticks=1); 操作,但它似乎没有延续到主脚本(因为它在函数内部,在包含文件中?。添加declare(ticks=1) 行在while(true) 循环导致信号立即通过之前(即sleep(1) 命令会导致一个滴答声,因此在从睡眠中醒来后,会处理信号)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-13
      • 2011-02-26
      • 2011-01-06
      • 1970-01-01
      • 2013-07-20
      • 1970-01-01
      • 2015-03-27
      • 2015-05-23
      相关资源
      最近更新 更多