Как я могу отправлять сообщения (или сигналы) из родительского процесса в дочерний процесс и наоборот в Perl?
Я пишу программу, которая управляет мути-процессами. Это то, что я сделал, и это прекрасно работает! но теперь я хочу отправлять сообщения от дочерних процессов родительскому процессу и наоборот (от родительского до дочернего), знаете ли вы лучший способ? Знаете ли вы, является ли то, что я сделал, правильным способом для того, что я хочу (отправлять сообщения или сигналы или делиться памятью от дочерних процессов к родительскому процессу и наоборот)?
Заранее спасибо!!
#!/usr/bin/perl -w
use strict;
use warnings;
main(@ARGV);
sub main{
my $num = 3; #this may change in the future (it would be dynamic)
my @parts = (1,4,9,17,23,31,46,50);
my @childs = ();
while(scalar(@parts)>0 || scalar(@childs)>0){
if(scalar(@parts)>0){
my $start = scalar(@childs) + 1;
for($start..$num){
my $partId = pop(@parts);
my $pid = fork();
if ($pid) {
print "Im going to wait (Im the parent); my child is: $pid. The part Im going to use is: $partId \n";
push(@childs, $pid);
}
elsif ($pid == 0) {
my $slp = 5 * $_;
print "$_ : Im going to execute my code (Im a child) and Im going to wait like $slp seconds. The part Im going to use is: $partId\n";
sleep $slp;
print "$_ : I finished my sleep\n";
exit($slp);
}
else{
die "couldn’t fork: $!\n";
}
}
}
print "before ret\n";
my $ret = wait();
print "after ret. The pid=$ret\n";
my $index = 0;
for my $value (@childs){
if($value == $ret) {
splice @childs, $index, 1;
last;
}
$index++;
}
}
}
2 ответа
Используйте kill. Если вы устанавливаете переменную в родительском элементе до своего форка, вам не нужны никакие внешние параметры.
my $parent_pid = $$; # Keep a reference to the parent
my $pid = fork();
if ($pid) {
print "Im going to wait (Im the parent);
my child is: $pid. The part Im going to use is: $partId \n";
push(@childs, $pid);
}
elsif ($pid == 0) {
my $slp = 5 * $_;
print "$_ : Im going to execute my code (Im a child) and Im going to wait like $slp seconds. The part Im going to use is: $partId\n";
sleep $slp;
print "$_ : I finished my sleep\n";
kill 20, $parent_pid # Send a signal to the parent, 20 is SIGCHLD
exit($slp);
}
Увидеть perldoc -f kill
для более подробной информации о вызове kill Другой вариант, если вам нужно сделать более сложные вещи, это использовать POE
Forks::Super
имеет хороший интерфейс для передачи сообщений между родительскими и дочерними процессами (межпроцессное взаимодействие). С помощью этого интерфейса вы можете передавать сообщения в STDIN ребенка и читать его из ручек STDOUT и STDERR.
use Forks::Super;
# set up channels to child's STDIN/STDOUT/STDERR with blocking I/O
my $pid = fork { child_fh => 'all,block' };
if ($pid) { # parent
$pid->write_stdin("Hello world\n");
my $msg_from_child = $pid->read_stdout(); # <-- "HELLO WORLD\n"
print "Message from child to parent: $msg_from_child";
}
elsif (defined($pid) && $pid == 0) { # child
sleep 1;
my $msg_from_parent = <STDIN>; # <-- "Hello world\n"
my $output = uc $msg_from_parent;
print $output;
exit 0;
}
else{
die "couldn’t fork: $!\n";
}