Re: Wait for background processes to complete



On Jan 13, 10:09 pm, Ben Morrow <b...@xxxxxxxxxxxx> wrote:
[please trim your quotations]

Quoth pgodfrin <pgodf...@xxxxxxxxx>:

On Jan 13, 9:51 pm, Ben Morrow <b...@xxxxxxxxxxxx> wrote:
Quoth pgodfrin <pgodf...@xxxxxxxxx>:

Here's what I want to do - run several commands in the background and
have the perl program wait for the commands to complete. Fork doesn't
do it, nor does wait nor waitpid.

<snip>

You need to either implement the behaviour you want with fork, exec and
waitpid (it's a little complicated, but entirely possible) or use
IPC::Run, something like

OK - would you have a good example of the fork-system-waitpid method -
not the same one that's in all the other posts or the camel book?

It's a more efficient use of everybody's time for you to use IPC::Run,
which has been written and tested by someone who understands these
issues and is prepared to solve them properly and portably, than it is
for a random Usenaut to provide you with a code snippet.

However, off the top of my head, completely untested, probably not
portable to Win32 or other non-POSIX systems, etc. etc.,

use POSIX qw/WNOHANG/;

{
my %kids;

$SIG{CHLD} = sub {
my ($pid, @died);
push @died, $pid while $pid = waitpid -1, WNOHANG;
delete @kids{@died};
};

sub background {
my (@cmd) = @_;

defined (my $pid = fork)
or die "can't fork for '$cmd[0]': $!";

if ($pid) {
$kids{$pid} = 1;
return;
}
else {
local $" = "' '";
exec @cmd or die "can't exec '@cmd': $!";
}
}

sub finish {
waitpid $_, 0 for keys %kids;
%kids = ();
}
}

while (<*.txt>) {
print "Copying $_\n";
background cp => $_, "$_.old";
}

finish;

This will break if used in conjunction with system or anything else that
relies on SIGCHLD, and an OO person would probably say it should be
implemented as an object. Use IPC::Run.

Ben

I really don't grasp the significance of having $kids{$pid} equal 1.
Can some enlighten me o this?
.



Relevant Pages

  • Re: tk - running always
    ... $pid = fork; ... Then how to end it, was either kill it with kill 9,. ... There seems to be a patch question with Tk and fork. ...
    (comp.lang.perl.tk)
  • Re: Wait for background processes to complete
    ... Fork doesn't ... nor does wait nor waitpid. ... my ($pid, @died); ... sub background { ...
    (comp.lang.perl.misc)
  • Re: OT: fork(): parent or child should run first?
    ... >>> called waitpid() on it? ... > it is actually prepared for the pid to be reclaimed. ... child did some work or slept before it exited. ... > active to an inactive array in the signal handler. ...
    (Linux-Kernel)
  • Re: Parallel::ForkManager pass a variable to global scope?
    ... package ForkManager2; ... sub start { ... my $kid; ... sub _waitpid {# Call waitpidin the standard Unix fashion. ...
    (comp.lang.perl.modules)
  • return value from waitpid()
    ... I want to use waitpid sys call with wnohang option to wait for a child process to terminate. ... How do I correct the program so that when the child exit, waitpid returns the child's pid? ...
    (comp.unix.bsd.freebsd.misc)