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