pcntl sigwaitinfo и обработчики сигналов
Я пишу демона, который периодически выполняет некоторую работу и некоторое время спит, прежде чем повторить ее снова. Но он все равно должен реагировать на внешние воздействия (т.Е. запрос на завершение) во время сна.
Мне удалось реализовать тайм-аут ожидания с сигналом ALRM и завершение с сигналом СРОКА (образец):
// ...
declare(ticks = 1);
function do_work()
{
echo "Doing some work.\n";
}
$term = FALSE;
$sighandler = function ($signal) use (&$term)
{
if ($signal === SIGTERM)
{
pcntl_alarm(0);
$term = TRUE;
echo "TERM HANDLER\n";
} else {
echo "ALRM HANDLER\n";
}
};
pcntl_signal(SIGALRM, $sighandler);
pcntl_signal(SIGTERM, $sighandler);
while (!$term)
{
do_work();
// Kick myself after 2 seconds
pcntl_alarm(2);
// Wait for alarm or termination
$signal = pcntl_sigwaitinfo(array(SIGTERM, SIGALRM), $info);
pcntl_signal_dispatch();
switch ($signal)
{
case SIGALRM: echo "ALRM SIGWI\n"; break;
case SIGTERM: echo "TERM SIGWI\n"; $term = TRUE; break;
}
}
// ...
Но, ради Бога, я не могу понять, почему никогда не вызывается sighandler. Я получаю следующий результат:
$ php sigsample.php
Doing some work.
ALRM SIGWI
Doing some work.
ALRM SIGWI
Doing some work.
TERM SIGWI
И в то же время, если я не установлю это обработчик сценарий умирает из-за сигнала необработчика.
Я что-то упускаю? Почему моя функция обработчика сигналов никогда не вызывается? Мешает ли pcntl_sigwaitinfo()?
И существуют ли какие-либо другие средства для одновременной реализации тайм-аута и обработки сигналов?
1 answers
Это не совсем неожиданно.
Вы запросили доставку обработчику сигнала (pcntl_signal(...)
), но затем также попросили принять сигнал без вызова каких-либо обработчиков (pcntl_sigwaitinfo(...)
). Ваша ОС решает, что произойдет в этом случае, и ваша ОС (как и моя) решает позволить pcntl_sigwaitinfo()
победить.
Предыстория
Процесс может получать ("страдать?") сигнал двумя различными способами:
-
асинхронная доставка
Сигнал индуцирует некоторое асинхронное действие, обычно завершающее процесс или вызывающее пользовательский обработчик.
pcntl_signal
регистрирует именно такой обработчик.Базовые вызовы, знакомые программистам на языке Си, следующие
signal
иsigaction
. -
синхронное принятие
Специальные системные функции отмечают, что сигнал находится в ожидании, и удаляют его из списка ожидающих, возвращая информацию о сигнале процессу.
pcntl_sigwaitinfo
является ли такое функция.Основными вызовами являются
sigwait
,sigwaitinfo
иsigtimedwait
.
Эти два способа доставки и принятия являются различными и не предназначены для совместного использования . AIX, например, просто запрещает "[c] текущее использование sigaction и sigwait".
(С вышесказанным связана концепция маски сигнала, которая может "блокировать" сигналы, эффективно заставляя их оставаться в ожидании до тех пор, пока они не будут приняты или "разблокированы" и доставлены.)