CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
forking many child processes

 



Peter Lom
Deleted

Sep 26, 2000, 11:23 PM

Post #1 of 5 (739 views)
forking many child processes Can't Post

Please help me in the following;

my main perl program needs to launch separate programs (some 10 or so),
wait until they finish and continue with the execution.

The following code does not work properly - - WHY


local @myChildren;
$ttime = time;
($s, $m,$h) = localtime($ttime);
print "\n Start in PARENT : hour=$h min=$m sec=$s\n";
$n=-1;
$children=10;

for ($i=0; $i<$children; $i++) {

if (!defined($myChildren[$0]=fork())) {
die "\n cannot fork: $! \n";
}

# execute if this is a child
# for e.g. 3 children I would try the following BUT this doesn't work either
# WHAT TO DO WITH 10+ PROCESSES ????

elsif ( (($myChildren[0] !=0) && ($myChildren[1]==0) && ($myChildren[2]==0) ) &#0124; &#0124;
(($myChildren[0] ==0) && ($myChildren[1]!=0) && ($myChildren[2]==0) ) &#0124; &#0124;
(($myChildren[0] ==0) && ($myChildren[1]==0) && ($myChildren[2]!=0) ) ) {

$n++;
system ("perl child.pl $n &");
}

# here the parent process is defined and PID positive
else {
$ttime = time;
($s, $m,$h) = localtime($ttime);
print "\n PARENT after child #=$i : hour=$h min=$m sec=$s\n";
}
} # end loop


for ($i=0; $i<$children; $i++) {
waitpid($myChildren[$i],0);
sleep(1);
}

# all children died, continue in PARENT
$ttime = time;
($s, $m,$h) = localtime($ttime);
print "\n PARENT all children are gone: hour=$h min=$m sec=$s\n";


========
### CHILD.PERL
$ttime = time;
($s, $m,$h) = localtime($ttime);
print "\n Start in CHILD no=$ARGV[0]: hour=$h min=$m sec=$s\n";

select undef, undef, undef, 2;

$ttime = time;
($s, $m, $h) = localtime($ttime);
print "\n END in CHILD no=$ARGV[0]: hour=$h min=$m sec=$s\n";



dws
Deleted

Sep 27, 2000, 12:08 PM

Post #2 of 5 (739 views)
Re: forking many child processes [In reply to] Can't Post

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>

for ($i=0; $i<$children; $i++) {
if (!defined($myChildren[$0]=fork())) {
die "\n cannot fork: $! \n";
}</pre><HR></BLOCKQUOTE>
Your first problem is using $0 instead of $i when storing the child pid.


Peter Lom
Deleted

Sep 27, 2000, 5:43 PM

Post #3 of 5 (739 views)
Re: forking many child processes [In reply to] Can't Post

Apologies for the typo - the original code read:

code
local @myChildren;
$ttime = time;
($s, $m,$h) = localtime($ttime);
print "\n Start in PARENT : hour=$h min=$m sec=$s\n";
$n=-1;
$children=10;

for ($i=0; $i<$children; $i++) {

if (!defined($myChildren[$i]=fork())) {
die "\n cannot fork: $! \n";
}

# execute if this is a child
# for e.g. 3 children I would try the following BUT this doesn't work either
# WHAT TO DO WITH 10+ PROCESSES ????

elsif ( (($myChildren[0] !=0) && ($myChildren[1]==0) && ($myChildren[2]==0) ) | |
(($myChildren[0] ==0) && ($myChildren[1]!=0) && ($myChildren[2]==0) ) | |
(($myChildren[0] ==0) && ($myChildren[1]==0) && ($myChildren[2]!=0) ) ) {

$n++;
system ("perl child.pl $n &");
}

# here the parent process is defined and PID positive
else {
$ttime = time;
($s, $m,$h) = localtime($ttime);
print "\n PARENT after child #=$i : hour=$h min=$m sec=$s\n";
}
} # end loop


for ($i=0; $i<$children; $i++) {
waitpid($myChildren[$i],0);
sleep(1);
}

# all children died, continue in PARENT
$ttime = time;
($s, $m,$h) = localtime($ttime);
print "\n PARENT all children are gone: hour=$h min=$m sec=$s\n";


========
### CHILD.PERL
$ttime = time;
($s, $m,$h) = localtime($ttime);
print "\n Start in CHILD no=$ARGV[0]: hour=$h min=$m sec=$s\n";

select undef, undef, undef, 2;

$ttime = time;
($s, $m, $h) = localtime($ttime);
print "\n END in CHILD no=$ARGV[0]: hour=$h min=$m sec=$s\n";


Thanks and regards
Peter



[This message has been edited by Peter Lom (edited 09-27-2000).]


dws
Deleted

Sep 27, 2000, 11:42 PM

Post #4 of 5 (739 views)
Re: forking many child processes [In reply to] Can't Post

Your test to determine if you're in a child process is needlessly complex. Try
<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>

for ( $i=0; $i<$children; $i++ ) {
if ( !defined($pid = fork()) ) {
die "cannot fork: $!\n";
}
elsif ( $pid ) {
# we're a parent, save the child
$child{$pid} = $i;
}
else {
# we're a child
$n = $i + 1;
system ("perl child.pl $n &");
}
}</pre><HR></BLOCKQUOTE>
This leaves you in a slightly better position to do bookkeeping as child processes die, since wait() returns the child's process id. (Reread the perlipc documentation for examples of how to use wait().)

Now what are you attempting to achieve by detaching the processes?


Peter Lom
Deleted

Oct 1, 2000, 3:00 AM

Post #5 of 5 (739 views)
Re: forking many child processes [In reply to] Can't Post

I am bitterly dissapointed by DWS's answer - he should not bother to contribute to this forum. If he knows, he should help. If not, he should admit. If he has not time, say so but to refer me to documentation (I did it and asked elswhere and it was not clear!!!) without bothering to cut/paste and run his own code which DOES NOT WORK - many thanks - I'll go elswhere.

The correct answer (found with the help Unix Network Programming book) is

DO NOT EXECUTE child.pl in a separate file as system "Perl child.pl parameters";
because kernel has problems to treat this as a child and also parent.

Consequently:
for($i=0; $<10; $++){
pid[$i]= fork();
if [$pid[$o]==0) {
&child( parameters);
}
}

sub child{
....
...

exit(1); # must be the last line
}

peter

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives