Язык программирования Perl
Язык программирования Perl читать книгу онлайн
Курс знакомит с языком программирования Perl, с его принципами, основными возможностями и особенностями в объёме, достаточном, чтобы начать разрабатывать прикладные и системные задачи, включая программирование для сети Интернет.
Курс является достаточно подробным введением в язык программирования Perl. Описывается уникальная культура Perl и особенности, отличающие его от других языков программирования и во многом обусловившие его популярность. Рассматриваются основные средства программирования на языке Perl версии 5.8. Разбираются богатые возможности языка для создания самых разных приложений, а также особый стиль программирования на Perl. Курс ориентирован на студентов, начинающих программистов или разработчиков, применяющих другие языки и желающих писать прикладные или системные программы на Perl.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
close READER; # канал закрывается
exit; # потомок завершает работу
}
Во время выполнения этого примера в стандартный выходной поток будет выведено следующее:
Потомок (PID -2032) прочитал:
Послано предком (PID 372):
1 2 3 4 5
Если нужно организовать передачу данных в обратном направлении, организуется канал, в котором передатчик будет в процессе-потомке, а приемник - в процессе-предке. Так как с помощью программного канала можно передавать данные только в одном направлении, то при необходимости двустороннего обмена данными между процессами создаются два программных канала на передачу в обоих направлениях.
Кроме программных каналов, процессы могут обмениваться информацией и другими способами: через именованные каналы (FIFO) и разделяемые области памяти, если они поддерживаются операционной системой, с помощью сокетов (что будет рассмотрено в следующей лекции) и при помощи сигналов.
В операционных системах имеется механизм, который может доставлять процессу уведомление о наступлении какого-либо события. Этот механизм основан на так называемых сигналах. Работа с ними происходит следующим образом. В программе может быть определен обработчик того или иного сигнала, который автоматически вызывается, когда ОС доставляет сигнал процессу. Сигналы могут отправляться операционной системой, или один процесс может с помощью ОС послать сигнал другому. Процесс, получивший сигнал, сам решает, каким образом реагировать на него, - например, он может проигнорировать сигнал. Перечень сигналов, получение которых можно попытаться обработать, находится в специальном хэше с именем %SIG. Поэтому допустимые идентификаторы сигналов можно вывести функцией keys(%SIG). Общеизвестный пример - сигнал прерывания выполнения программы INT, который посылает программе операционная система по нажатию на консоли сочетания клавиш Ctrl+C. Как устанавливать обработчик конкретного сигнала, показано на примере обработки сигнала INT:
# устанавливаем обработчик сигнала INT
$SIG{INT} = &sig_handler; # ссылка на подпрограмму
# начало основной программы
print "Работаю в поте лица...n" while (1); # бесконечный цикл
sub sig_handler { # подпрограмма-обработчик сигнала
$SIG{INT} = &sig_handler; # переустанавливаем обработчик
print "Получен сигнал INT по нажатию Ctrl+Cn";
print "Заканчиваю работу!n";
exit; # завершение выполнения программы
}
Выполнение примера сопровождается выводом сообщений, подтверждающих обработку поступившего сигнала:
Работаю в поте лица...
Получен сигнал INT по нажатию Ctrl+C
Заканчиваю работу!
Примером реальной программы, выполняющейся в бесконечном цикле, может служить любой сервер, ожидающий запросов от клиентских программ и перечитывающий свой конфигурационный файл после получения определенного сигнала (обычно HUP или USR1). Если необходимо временно игнорировать какой-то сигнал, то соответствующему элементу хэша %SIG присваивается строка 'IGNORE'. Восстановить стандартную обработку сигнала можно, присвоив соответствующему элементу %SIG строку 'DEFAULT'.
Процесс может посылать сигналы самому себе, например, для отслеживания окончания запланированного периода времени (для обработки тайм-аута). В приведенном примере длительная операция прерывается по истечении указанного промежутка времени:
# устанавливаем обработчик сигнала ALRM (будильник)
$SIG{ALRM} = sub { die "Timeout"; }; # анонимная подпрограмма
$timeout = 3600; # определяем величину тайм-аута (сек.)
eval { # блок обработки возможной ошибки
alarm($timeout); # устанавливаем время отправки сигнала
# некая длительная операция:
print "Работаю в поте лица...n" while (1);
alarm(0); # нормальное завершение операции
};
# в специальной переменной [email protected] - сообщение об ошибке
if ([email protected] =~ /Timeout/) { # проверяем причину ошибки
print "Аварийный выход по истечении времени!";
}
Отправка сигнала одним процессом другому также используется в качестве средства взаимодействия процессов. Сигнал отправляется процессу с помощью функции kill(), которой передаются два аргумента: номер сигнала и PID процесса. Схему реагирования порожденного процесса на сигналы, получаемые от процесса-предка, можно увидеть на следующем учебном примере:
my $parent = $$; # PID родительского процесса
my $pid = fork(); # 'разветвить' текущий процесс
# fork вернет PID потомка в процессе-предке и 0 в потомке
die "fork не отработал: $!" unless defined $pid;
if ($pid) { # ---------- родительский процесс ----------
print "Начался предок PID $$n";
for (1..3) {
print "Предок PID $$ работает $_n";
print "Предок PID $$ отправил сигналn";
kill HUP, $pid;
sleep 2; # 'заснуть' на 2 секунды
}
print "Закончился предок (PID $$)n";
}
unless ($pid) { # ---------- дочерний процесс ----------
my $counter = 0; # счетчик полученных сигналов
$SIG{HUP} = sub { ### обработчик сигнала ###
$counter++;
print "tПотомок получил $counter-й сигнал!n";
}; ### конец обработчика сигнала ###
print "tНачался потомок PID $$ предка $parentn";