- alarm SECONDS
- alarm
Подготавливает сигнал SIGALRM, который будет передан текущему процессу по истечении указанного количества секунд. Если SECONDS не указано, используется значение из
$_
. (на некоторых машинах, к сожалению, прошедшее время может быть меньше или больше указанного на одну секунду, в зависимости от того, как считаются секунды. Из-за этого планировщик процессов может отложить доставку сигнала на некоторое время).Одновременно может быть активен только один таймер. Каждое новое обращение к функции отключает предыдущий таймер, таким образом, значение
SECONDS
, равное0
, может использоваться для отключения предыдущего таймера без запуска нового. Возвращаемое значение представляет остаток времени предыдущего таймера.Чтобы задать время подачи сигналов с большей точностью, чем одна секунда, можно применить функцию
ualarm()
, которую предоставляет модуль Time::HiRes (можно найти на CPAN, начиная с Perl 5.8 является частью дистрибутива). Также можно использовать 4х-аргументную версиюselect()
, оставляя первые три аргумента неопределенными. Еще один вариант задать миллисекунды предоставляет интерфейсsyscall
для обращения к setitimer(2), если система поддерживает его. См. perlfaq8 подробнее.Обычно смешивание вызовов
alarm
иsleep
является ошибкой, потому что в вашей системе функцияsleep
может быть внутренне реализована с использованием механизма системного вызова alarm(2).Если вы планируете использовать
alarm
для формирования тайм-аута системного вызова, необходимо использовать паруeval
/die
. Не стоит полагаться на то, что, в случае, если системный вызов не отработает должным образом, переменная$!
будет содержать значениеEINTR
, поскольку на некоторых операционных системах, Perl устанавливает обработчики сигналов таким образом, чтобы они перезапускали системные вызовы. А вот связкаeval
/die
работает всегда, возможные сложности описаны в perlipc.eval { local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n обязателен alarm $timeout; $nread = sysread SOCKET, $buffer, $size; alarm 0; }; # если вышли по тайм-ауту $timeout if ($@) { die unless $@ eq "alarm\n"; # обработка неожиданных ошибок } # все в порядке, сработали пределах установленного времени $timeout else { #... }
За более подробной информацией обратитесь к perlipc.
Прочие источники: http://valera.asf.ru/perl/help/
http://perl5doc.ru/en/f-alarm