внимание – perl сигнализира!

Както всички знаем 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

Твоят коментар