Hello,
I have a set of resources that I would like to process asynchronously, unfortunately I don't have the authority to install one of the perl modules that would make this a sinch, like POE.
So I'm falling back on the oldschool Fork and process method. However I'm finding choosing the best IPC method difficult and I was wondering if someone here could help.
This is the kind of structure I'm thinking about:
#!/bin/perl
use strict;
# setup shared resource between children and parent
my @resource = qw(thing1 thing2 another_thing some more things which m
+ust be more than the pool of processes);
my @todo = (0..$#resource); # indexes of shared resources to process
my $parent = $$;
my @children;
# spawn pool of child processes
for (1..10) {
# setup 2 way communication (pipe?)
...
my $pid;
unless ($pid = fork()) {
# child process
# stop if signaled
local $SIG{HUP} = sub { $end = 1 };
# work until signaled to die
while(1) {
# read instruction from parent
my $message = ...
# if finished let the child die
if ($end or $message eq "END") {
# send message that child is exiting
...
exit();
# if we have recieved an index to a shared res
+ource to process do so
} elsif ($message =~ /^[0-9]+/) {
if ($message >= @resource) {
# send message that child is exiting
...
die "Resource unavailable\n";
}
# process shared resource
process($resource[$message]);
} else {
# send message that child is exiting
...
die "Caught unexpected communication\n";
}
}
}
push @children, $pid;
}
# keep count of the number of living children
$kids = @children;
print "Forked $kids children\n";
# send messages to children to begin processing
... for(@todo[0..$#children]);
while (@children > 0) {
# read messages from children into $message and $child
...
# receive index of shared resource if complete
if ($message =~ /^[0-9]+$/) {
# remove from todo list
@todo = grep { $_ != $message } @todo;
last unless (@todo); # stop if no more to do
# message $child to do next @todo item
...
} elsif($message eq "END") { # message from child of exit
# remove child from pool
@children = grep { $_ != $child } @children;
}
}
# make sure the children have stopped
kill 'HUP', @children;
print "Complete\n";