Когда скрипт PHP <5.3.0 получает сигналы? - PullRequest
2 голосов
/ 29 апреля 2010

У меня есть 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 без возможности явного вызова синтаксического анализа очереди? Могу ли я вставить в этот цикл ожидания какую-то другую бесполезную команду, которая вызовет там анализ очереди сигналов?

1 Ответ

2 голосов
/ 29 апреля 2010

Исправлена ​​собственная проблема: ответом является объявление " ticks ". В ходе запуска процесса Daemon я выполнил действие declare(ticks=1);, но казалось, что оно не переносится на основной сценарий (так как он был внутри функции, во включаемом файле?. Добавление строки declare(ticks=1) до того, как цикл while(true) заставляет сигналы проходить немедленно (т. е. команда sleep(1) вызывает тик, поэтому после пробуждения сигналы обрабатываются).

...