Есть ли какие-либо сигналы POSIX, которые я мог бы использовать в моей программе Perl для создания событийно-ориентированного программирования? В настоящее время у меня есть многопроцессорная программа, которая может взаимодействовать друг с другом, но мой родительский поток может слушать только одного ребенка за раз.
foreach (@proc) {
sysread(${$_}{'read'}, my $line, 100); #problem here
chomp($line);
print "Parent hears: $line\n";
}
Проблема в том, что родитель находится в состоянии постоянного ожидания, пока не получит сигнал от первого ребенка, прежде чем он сможет продолжить. Я полагаюсь на «трубу» для моего общения.
Мое текущее решение очень похоже на: Как я могу использовать `pipe` для облегчения межпроцессного взаимодействия в Perl?
Если возможно, я бы хотел положиться на событие $ SIG {...} или любое решение, не относящееся к CPAN.
Обновление:
Как упоминал Джонатан Леффлер, kill может использоваться для отправки сигнала:
убить 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);
};
- Но как мне получить мой исходный / дочерний pid, который сигнализировал родителю?
Пусть ребенок идентифицирует себя в своем сообщении.
- Что произойдет, если двое детей подадут сигнал USR1 одновременно?
Обновление 2: решение
Я пошел с выбором, который использовал векторный подход для неблокирующего ввода-вывода.
Для тех, кто сталкивается с этим потоком, проверьте: http://docstore.mik.ua/orelly/perl/cookbook/ch07_14.htm, поскольку он охватывает как векторный путь, так и модуль IO :: Select. Я понимаю, что модуль IO :: Select был бы более элегантным, но меня больше интересовало изучение новой механики 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
}
}