Както всички знаем perl може всичко. Следователно може да прихваща сигнали под unix. Също така може да подлудява хората.
Сигналите се прихващат лесно : $SIG{INT} = \&sigint_handler;
Даже работят. Има обаче няколко много важни момента, които не трябва да се пропускат:
- сигналите в perl са restartable. Всяко блокващо (бавно) системно извикване (като например
read
,wait
,select
,recv
) се рестартира самоинициативно след получване на сигнала и на практика почти не спира своята работа. - от версия 5.7.3 насам прихващането на сигналите е безопасно. Представете си, че сте насредата на изпълнението на ф-ята
funcshun
. Половината системни изисквания необходими за работата ѝ, например някаква инициализация на памет, са били изпълнени и точно тогава получите сигнал, в чийто handler също се викаfuncshun
. Инициализацията ще мине още веднъж преди да е свършило изпълнението на предната функция и има немалък шанс да осъмнем с core dump. Unix C програмистите са свинкнали в своите signal handler-и просто вдигат флаг и нищо друго. В perl този труд не е необходим. Виртуалната машина се грижи тя да прихване сигнала и да изпълни нашия код, когато сметне, че вече няма какво да се омаже. - горната техника на отложено достигане на сигналите до нашите handler-и е нож с две остриета (Забележка: отложено е само извикването на нашия код – на по-ниско ниво perl приема сигнала точно когато трябва и нито миг по-късно). Предпазва ни от непредвидени грешки и усложнения, но понякога може бъде и не особено желана. Ето един такъв случай: ползвам Net::Pcap и в един момент викам неговата функция
loop
, която вътрешно вика в повечето случаиread
илиrecv
и когато се опитам да прихвана някой сигнал (освен с INT пробвах и с USR1 и с още няколко), то моят код се вика, чак когато пристигне следващия пакет (модула се ползва за следене на мрежови пакети на даден интерфейс), което е ужасно дразнещо защото карам потребителя да чака ужасно много време. Пък и докато пиша аз съм си потребител, което значи че аз трябва да чакам ужасно много време. А не искам! - установяването на променливата на обкръжението
PERL_SIGNALS
на"unsafe"
ни гарантира, че веднага при получване на сигнал виртуалната машина ще изпълния нашия perl код, даден за handler на сигнала. Сигурност срещу удобство. - Полезни връзки: perlipc и по-специално Deferred Signals