in reply to forking and monitoring processes

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.

Replies are listed 'Best First'.
Re^2: forking and monitoring processes
by Anonymous Monk on Jan 08, 2005 at 17:48 UTC
    Hello,

    Thanks for the response, it makes things a lot clearer. A few questions I had was:

    my $pid = open my $fh, "-|", $_

    This means pipe open the process to the filehandler right? I wasn't sure what the "-" in " -|" meant.

    Also, after looking at each line, I would like to store the output of each child process into different files. So for process 1, I want to store the output into proc1.txt etc. But when processing each line, I am only aware of the pid and not the process running so I was wondering how I can write to the file proc1.txt if I only know proc1's pid is running and so on?

    Thanks.

      But when processing each line, I am only aware of the pid and not the process running

      That's why I changed to a hash of arrays to store the PIDs and process information. You can get the program name by $pid{$fh}[1], or put more information into that array as necessary.

      Update: your question about -| can be fully answered by reading open's documentation. The short answer is it opens a process for reading.

        Hello,

        Thanks for reply. When I run the program, the processes seems to start but the program seems to timeout at the select command can_read. Since it a dir command, output is expected immediatly, I was not sure why it was timing out.

        #! perl use IO::Select; my %pids; my $s = IO::Select->new(); my @proc = (qw(C M)); for ( <@proc> ) { my $cmd = "dir $_:"; print "this is my cmd: $cmd \n\n"; my $pid = open my $fh, "-|", $cmd or warn "Could not fork&open $cmd: $!" and next; $pids{$fh} = [ $pid, $_ ]; $s->add($fh); } while (my @ready = $s->can_read) { for my $fh (@ready) { if (eof $fh) { delete $pids{$fh}; $s->remove($fh); next; } my $line = <$fh>; if ($line =~ /Rational/) { chomp $line; print "Found 'Rational' in '$line' from $pid{$fh}[1]\n"; kill 15, values %pids; } } }

        Thanks.