Простой пример использования POE::Component::Child
С помощью компоненты POE::Component::Child мы создаем POE-программу, которая для выполнения некоторых задач создает дочерние процессы.
Сначала создается и выполняется первый дочерний процесс, после завершения работы первого - второй. Когда и второй закончит свою работу - программа завершается.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
#!/usr/bin/perl use warnings; use strict; use POE; use POE::Component::Child; my $debug = 0; # установка соответствия событий и их обработчиков my %events = ( stdout => "my_stdout", stderr => "my_stderr", error => "my_error", done => "my_done", died => "my_died", ); POE::Session->create( package_states => ["main" => [values(%events)]], inline_states => { _start => sub { $_[KERNEL]->alias_set("main"); }, _stop => sub { print "_stop" if $debug; }, } ); my $c = POE::Component::Child->new( events => \%events, debug => $debug ); # запускаем первый дочерний процесс $c->run("ls"); # запускаем второй дочерний процесс $c->run("ps", "-f"); POE::Kernel->run(); exit; sub my_stdout { my ($self, $args) = @_[ARG0 .. $#_]; print $args->{out}, $/; } sub my_stderr { my ($self, $args) = @_[ARG0 .. $#_]; print ">> $args->{out}"; } sub my_done { print "child done\n"; } sub my_died { print "child died!\n"; } sub my_error { my ($self, $args) = @_[ARG0 .. $#_]; print "$args->{error}\n"; } |
Результат работы скрипта:
|
1 2 3 4 5 6 7 8 9 10 |
$ perl poe_child.pl poe_child.pl simple_ping.pl simple_server.pl child done UID PID PPID C STIME TTY TIME CMD 1366 18169 30283 0 15:41 pts/12 00:00:00 perl poe_child.pl 1366 18173 18169 0 15:41 pts/12 00:00:00 ps -f 1366 30283 30281 0 Aug20 pts/12 00:00:00 bash child done |
Краткий обзор возможностей компонента POE::Component::Child
Компонент POE::Component::Child является оболочкой для POE::Wheel::Run. Делает использование POE::Wheel::Run более удобным и предоставляет объектно-ориентированный интерфейс к нему. Дочерние процессы создаются непосредственно POE::Wheel::Run, с помощью fork.
Методы компонента
new
Метод создает экземпляр компонента. На вход принимает либо хеш, либо ссылку на хеш.
- alias - Задает имя сессии, по которому к ней можно будет обращаться при вызове post. По умолчанию - main.
- events - Ссылка на хеш, который содержит список событий для текущего компонента, со ссылками на соответствующие обработчики. Варианты допустимых событий: stdout, stderr, done, died, error.
- debug - установка флага включает вывод отладочной информации.
run
Метод принимает список команд и параметров для запуска. Возвращает id wheel, который может пригодиться, если запускается несколько разных команд.
write
Метод может использоваться для отправки массива информации дочернему процессу.
quit
Организует корректное завершение программ из дочерних сессий. Однако, полное закрытие дочерних процессов организуется с помощью метода shutdown().
kill
Посылает сигнал для насильственного завершения программ.
shutdown
Метод завершает работу всех дочерних процессов и закрывает их.
wheelid
Используется для получения wheelid. В дальнейшем может использоваться для вызова методов, например, kill() или shutdown().
События дочерних процессов
Обработчики событий всегда получают на вход два аргумента: ARG0 и ARG1. Первый содержит ссылку на объект, второй - хеш с параметрами.
Например, при выводе результатов в STDOUT, функции-обработчику передавался в качестве ARG1 хеш, с ключами out и wheel. Out содержал выводимую строку данных, wheel - id.
stdout
Данное событие генерируется при любом выводе данных. Вывод данных осуществляется построчно. В нашем примере для вывода 3х-строк со списком процессов, вызов события stdout и его обработчика my_stdout осуществляется 3 раза.
stderr
Событие генерируется при любом выводе в STDERR.
done
Генерируется после завершения работы дочернего процесса.
died
Вызывается в случае аварийного завершения дочернего процесса. Является взаимоисключающим с done.
error
Событие генерируется, если дочерний процесс вернул ошибку.