Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Wait for background processes to finish? How? 1

Status
Not open for further replies.

Dudek

Technical User
Jan 14, 2002
27
MY

Hi there...

How do i run 3 different processes in a row and then run a 4th process once all three before have finished. Something like:

`p1 &`;
`p2 &`;
`p3 &`;

(Once p1, p2 and p3 has finished){`run p4`;}


TIA
JD
 
There are several ways to launch a child process from Perl.
If all you want to do is to run each of the processes in order,
then the system function might be what you are looking for.

Note that 'system' does not hand back output from the called program.
Rather, it returns the exit code from the called program.
It returns '-1' if it fails to execute the requested program.

Each system call runs the indicated program to completion and
then returns to continue executing the main Perl program.

See perldoc -f system for more details.

An example with some very simple error checking.
Code:
$success = system("p1");
if ($success == '-1') { print "program didn't run, $!\n"; }
$success = system("p2");
if ($success == '-1') { print "program didn't run, $!\n"; }
$success = system("p3");
if ($success == '-1') { print "program didn't run, $!\n"; }
$success = system("p4");
if ($success == '-1') { print "program didn't run, $!\n"; }

Since you can catch the exit value of the called program,
your error checking could be a lot stronger.

HTH 'hope this helps

If you are new to Tek-Tips, please use descriptive titles, check the FAQs, and beware the evil typo.
 
Thanks for the response, but i think i made a mistake in the post...

What i need is to have p1, p2 and p3 to run simultaneously and then once all of these are finished, then only run p4. I *think* this could be done using threads, but is there any way of doing this without threads? Something like...

$pid1 = fork();
$pid1;
if ($pid1){
$pid2= fork();
$pid2;
if ($pid2){`p1`; exit(0);}
else {`p2`; exit(0);}
}
else ($pid3){`p3`;}

`p4`;

or something like this...? Not sure if it is correct. I should also say that i am running in Unix..

TIA again

JD
 
if(fork()){
sleep(5); # parent here, give everything time to start
} elsif(!fork()) {
system(p1); # child
exit;
} elsif(!fork()) {
system(p2); # child
exit;
} elsif(!fork()) {
system(p3); # child
exit;
}
# parent here, wait for all child processes
wait();
Mike
michael.j.lacey@ntlworld.com
Email welcome if you're in a hurry or something -- but post in tek-tips as well please, and I will post my reply here as well.
 
Mike..

Sorry for my late reply.. havent been around for a week.. anyway, i tried your sample script, and the thing is, i am not sure where to put my process/program p4 such that p4 runs *after* p1, p2, and p3 *completes*...not after they start Heres what i did..

if(fork()){
sleep(5);
# parent here, give everything time to start

} elsif(!fork()) {
print ("1\n"); # child
sleep (10);
print ("1 done\n");
exit;
} elsif(!fork()) {
print ("2\n"); # child
sleep (2);
print("2 done \n");
exit;
} elsif(!fork()) {
print ("3\n"); # child
sleep(3);
print ("3 done \n");
exit;
}
# parent here, wait for all child processes
wait();


i need to know where to put something like print ("p4"); such that the output becomes like:

1
2
3
2 done
3 done
1 done
p4

TIA again...

JD
 
Hi JD,

Put your P4 stuff after the wait(); line. Mike
michael.j.lacey@ntlworld.com
Email welcome if you're in a hurry or something -- but post in tek-tips as well please, and I will post my reply here as well.
 
Hi there again, Mike..
Sorry for the late response, but been pretty busy lately,

Anyway, tried using the script like below:


if(fork()){
sleep(5);
# parent here, give everything time to start
exit();
} elsif(!fork()) {
print ("1\n"); # child
sleep (20);
print ("1 done\n");
exit;
} elsif(!fork()) {
print ("2\n"); # child
sleep (10);
print("2 done \n");
exit;
}
elsif(!fork()) {
print ("3\n"); # child
sleep(3);
print ("3 done \n");
exit;
}
# parent here, wait for all child processes
wait();

print ("All done \n");
exit;

It will come out with:
1
2
3
3done
All done
2done
1done

It seems that the "All done" comes out after the first of the 3 forks finish.. I was wondering whether it would be possible for the "All done" comes out after *all three* finishes.. something like
1
2
3
3done
2done
1done
All done

Is that possible?

Again, TIA

JD
 
Ok, a different approach. The following scripts works fine on my lunux box but on my NT machine.... well, never mind.

This let me see what I was doing more clearly. A single parent process does nothing but kick off 5 child processes and then wait for each, in turn, using waitpid().

The child processes wait for five seconds, do their work and then exit().
[tt]
my @pids; # to hold process id's of child processes
my $pid_index = 0;
my $max_pid_index = 4;
my $pid;

while($pid_index <= $max_pid_index){
if($pids[$pid_index] = fork()){
# this is the parent, just spins round and has childrem
$pid_index++;
} else {
# this is the child, does a single task and then exits
sleep(5);
print &quot;child $pid_index\n&quot;;
exit(0);
}
}

print &quot;waiting...\n&quot;;
foreach $pid (@pids){
waitpid($pid,0);
}
print &quot;All done\n&quot;;
[/tt]

the output I get on my linux box is as you would expect:
./waiter.pl
waiting...
child 2
child 0
child 1
child 3
child 4
All done
Mike
michael.j.lacey@ntlworld.com
Email welcome if you're in a hurry or something -- but post in tek-tips as well please, and I will post my reply here as well.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top