Launching 2 background processes with fork - how to make wait() work?

M

mrstevegross

Hi folks. I need to launch two "background" processes and wait for
them both to finish before proceeding. I have followed the advice
elsewhere on this forum to use the fork & wait solution. Here's what I
have so far:

my $proc1_pid = fork;
if(not $proc1_pid) {
exec("proc1");
}
my $proc2_pid = fork;
if(not $proc2_pid) {
exec("proc1");
}
wait();
doSomething();

Unfortunately, wait() doesn't appear to work--the doSomething() line
is processed immediately, even though proc1 and proc2 have not
terminated.

Am I doing something wrong? Is there something quirky about having two
background processes instead of one?

Thanks,
--Steve
 
M

Marc Girod

Is there something quirky about having two
background processes instead of one?

Nothing quirky.
Test separately whether you pids are defined or 0,
to account for failures to fork.

Look at the value returned by wait...
I am afraid it returns for each completing process, so you want to
loop
until both have exited (?)
You can also use waitpid, and wait for them explicitely
(I need to do that because I have one other background process
which will exit in the END clause)...

my %family;
for ... {
if (my $pid = fork) {
$family{$pid}++;
} else {
die "cannot fork: $!" unless defined($pid);
}
}
while (%family) {
foreach my $kid (keys %family) {
delete $family{$kid} if waitpid($kid, WNOHANG);
}
sleep 1;
}

Marc
 
D

derykus

Hi folks. I need to launch two "background" processes and wait for
them both to finish before proceeding. I have followed the advice
elsewhere on this forum to use the fork & wait solution. Here's what I
have so far:

  my $proc1_pid = fork;
  if(not $proc1_pid) {
    exec("proc1");
  }
  my $proc2_pid = fork;
  if(not $proc2_pid) {
    exec("proc1");
  }
  wait();
^^^^^^^^

As mentioned briefly in one of the responses, you can also wait-block
on those 2 specific pids:

waitpid($proc1_pid, 0); # perldoc -f waitpid
waitpid($proc2_pid, 0);

However, you'll usually want to use the non-
blocking WNOHANG to reap them asynchronously.
You may need to check $? child status too if
that impacts proceeding to doSomething().
 
J

J. Gleixner

mrstevegross said:
Hi folks. I need to launch two "background" processes and wait for
them both to finish before proceeding. I have followed the advice
elsewhere on this forum to use the fork & wait solution. Here's what I
have so far:

my $proc1_pid = fork;
if(not $proc1_pid) {
exec("proc1");
}
my $proc2_pid = fork;
if(not $proc2_pid) {
exec("proc1");
}
wait();
doSomething();

Unfortunately, wait() doesn't appear to work--the doSomething() line
is processed immediately, even though proc1 and proc2 have not
terminated.

Am I doing something wrong? Is there something quirky about having two
background processes instead of one?

Take a look at using Parallel::ForkManager. Might be a little
much for only two processes, but it makes running things in
parallel very easy.
 
X

Xho Jingleheimerschmidt

As mentioned briefly in one of the responses, you can also wait-block
on those 2 specific pids:

waitpid($proc1_pid, 0); # perldoc -f waitpid
waitpid($proc2_pid, 0);

However, you'll usually want to use the non-
blocking WNOHANG to reap them asynchronously.

Since he has nothing useful to do until both finish, what would be the
point of WNOHANG? Seems like it would just burn CPU faster.


Xho
 
C

CDeRykus

Since he has nothing useful to do until both finish, what would be the
point of WNOHANG?  Seems like it would just burn CPU faster.

Agreed, that's the case here. I was just
suggesting WNOHANG is usually the idiom in
other scenarios with more than one kid if
you could be doing something else.

Seems like even here though, async might be
an advantage if the parent needs all kids to
succeed in order to continue. That is, if
there's a kid failure, async would be more
likely to catch it early so the parent could
abort. Of course, if the blocking wait's do
happen to target the failing kid early in the
coding, there'd be no advantage.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,019
Latest member
RoxannaSta

Latest Threads

Top