Is there any POSIX signals that I could utilize in my Perl program to create event-driven programming? Currently, I have multi-process program that is able to cross communicate but my parent thread is only able to listen to listen at one child at a time.
foreach (@proc) {
sysread(${$_}{'read'}, my $line, 100); #problem here
chomp($line);
print "Parent hears: $line\n";
}
The problem is that the parent sits in a continual wait state until it receives it a signal from the first child before it can continue on. I am relying on 'pipe' for my intercommunication.
My current solution is very similar to: http://stackoverflow.com/questions/2558098/how-can-i-use-pipe-to-facilitate-interprocess-communication-in-perl
If possible I would like to rely on a $SIG{...} event or any non-CPAN solution.
Update:
As Jonathan Leffler mentioned, kill can be used to send a signal:
kill USR1 => $$; # send myself a SIGUSR1
My solution will be to send a USR1 signal to my child process. This event tells the parent to listen to the particular child.
child:
kill USR1 => $parentPID if($customEvent);
syswrite($parentPipe, $msg, $buffer);
#select $parentPipe; print $parentPipe $msg;
parent:
$SIG{USR1} = {
#get child pid?
sysread($array[$pid]{'childPipe'}, $msg, $buffer);
};
- But how do I get my the source/child pid that signaled the parent? Have the child Identify itself in its message.
- What happens if two children signal USR1 at the same time?
Update 2: Solution
I went with a select that utilized a vector approach for non-blocking IO. For those that come across this thread check out: http://docstore.mik.ua/orelly/perl/cookbook/ch07_14.htm as it covers both the vector way and the IO::Select module. I understand the IO::Select module would have been more elegant, but I was more interested in learning new mechanics of Perl. Thank you everyone for your help.
Exert:
$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
}
}