You can use a forking form of open, and IO::Select. Here is an example:
use IO::Select;
my %pid;
my $s = IO::Select->new();
for (qw(proc1 proc2 proc3)) {
my $pid = open my $fh, "-|", $_
or warn "Could not fork&open '$_': $!"
and next;
$pid{$fh} = [ $pid, $_ ];
$s->add($fh);
}
while (my @ready = $s->can_read) {
for my $fh (@ready) {
if (eof $fh) {
delete $pid{$fh};
$s->remove($fh);
next;
}
my $line = <$fh>;
if ($line =~ /desktop/) {
chomp $line;
print "Found 'desktop' in '$line' from $pid{$fh}[1]\n";
kill 15, map {$_->[0]} values %pid;
}
}
}
Update: changed to a hash instead of an array for storing the PIDs
Another update: fixed bugs introduced by last-minute changes to hash structure.