Есть ли какие-либо сигналы POSIX, что я мог использовать в своей программе Perl для создания событийно-ориентированного программирования? В настоящее время у меня есть программа мультипроцесса, которая может пересечься, связываются, но мой родительский поток только может послушать для слушания в одном ребенке за один раз.
foreach (@proc) {
sysread(${$_}{'read'}, my $line, 100); #problem here
chomp($line);
print "Parent hears: $line\n";
}
Проблема состоит в том, что родитель находится в непрерывном состоянии ожидания, пока он не получает его сигнал от первого ребенка, прежде чем он сможет продвинуться. Я полагаюсь на 'канал' для своего общения.
Мое текущее решение очень похоже на: Как я могу использовать 'канал' для упрощения межпроцессного взаимодействия в Perl?
Если возможный я хотел бы полагаться на $SIG {...} Событие или любое non-CPAN решение.
Обновление:
Как Jonathan Leffler упомянул, уничтожение может использоваться для отправки сигнала:
уничтожьте USR1 => $$; # отправляют мне SIGUSR1
Мое решение будет состоять в том, чтобы отправить сигнал USR1 в мой дочерний процесс. Это событие говорит родителю слушать конкретного ребенка.
ребенок:
kill USR1 => $parentPID if($customEvent);
syswrite($parentPipe, $msg, $buffer);
#select $parentPipe; print $parentPipe $msg;
родитель:
$SIG{USR1} = {
#get child pid?
sysread($array[$pid]{'childPipe'}, $msg, $buffer);
};
Обновление 2: решение
Я пошел с выбором, который использовал векторный подход для неблокирования IO. Для тех, которые сталкиваются с этим выездом потока: http://docstore.mik.ua/orelly/perl/cookbook/ch07_14.htm, поскольку это покрывает и векторный путь и IO:: Выберите модуль. Я понимаю IO:: Избранный модуль был бы более изящным, но я больше интересовался изучением новой механики Perl. Поблагодарите Вас все за свою справку.
Проявите:
$rin = '';
# repeat next line for all filehandles to poll
vec($rin, fileno(FH1), 1) = 1;
vec($rin, fileno(FH2), 1) = 1;
vec($rin, fileno(FH3), 1) = 1;
$nfound = select($rout=$rin, undef, undef, 0);
if ($nfound) {
# input waiting on one or more of those 3 filehandles
if (vec($rout,fileno(FH1),1)) {
# do something with FH1
}
if (vec($rout,fileno(FH2),1)) {
# do something with FH2
}
if (vec($rout,fileno(FH3),1)) {
# do something with FH3
}
}
Вы можете использовать select для мониторинга каналов связи (примечание: если вы используете Win32, select можно использовать только на сокете).
Итак, вы можете использовать такой код:
use IO::Select;
use IO::Handle;
...
$_->blocking(0) for @handles;
while( 1 ) {
my $s = IO::Select->new( @handles );
for my $h ( $s->can_read( 1 ) ) {
my $data = read_handle($h);
process_handle_data( $data );
}
}
sub read_handle {
my $h = shift;
my $got = '';
1 while read( $h, $got, 1024, length $got );
return $got;
}
Взгляните на пример UDP в perlipc. Он использует встроенный select. Я предпочитаю основной модуль IO :: Select
встроенному select
, он намного легче читается.
Обновление: Вам действительно стоит подумать об использовании структуры событий, такой как POE, Event или Coro. В этой ветке perlmonks есть неплохой список опций. Не бойтесь CPAN.
Если вы хотите программировать, управляемое событиями, взгляните на один из модулей событий CPAN, например POE , Coro или AnyEvent до того, как вы изобрели свою вещь.
Чтобы ответить на прямой вопрос, SIGUSR1 и SIGUSR2 предназначены для «определяемых пользователем» целей, поэтому вы можете их использовать.
Возможно, вам лучше взглянуть на уже существующую систему.