Re: Wait for background processes to complete



[please trim your quotations]

Quoth pgodfrin <pgodfrin@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

.



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: avoid multiple script startup overhead
    ... spawning of new perl and ksh interpreters to run various scripts is ... interpreter, ... defined $pid or die "didn't fork $!"; ...
    (comp.lang.perl.misc)
  • Re: Porting on FreeBSD 53
    ... You did suspend ) SIGCHLD before the fork? ... avant FORK: pid 71995. ... Grand parent waiting for a signal. ... int main(int argc, ...
    (freebsd-hackers)