T
trxrse
Hi, everyone
can you tell me please what's happening here?
This piece of code is supposed to launch 3 children processes and to
keep track of each one when they finish.
THE PROBLEM: SOMETIMES (50% OF THE TIME) THE LAST PROCESS NEVER RETURNS
THE USR1 MESSAGE TO THE PARENT.
For example:
../fork3
Started Wed Jan 10 09:23:36 2007
Forked by Wed Jan 10 09:23:36 2007
I am finished... Process 1
Look:3 $nfound:0
Look:2 $nfound:0
Look:1 $nfound:1
Wed Jan 10 09:23:37 2007 - Completed 1
I am finished... Process 2
Look:3 $nfound:0
Look:2 $nfound:0
Look:1 $nfound:0
I am finished... Process 3
Look:3 $nfound:0
Look:2 $nfound:2
Wed Jan 10 09:23:39 2007 - Completed 2
Look:1 $nfound:0
And now the code:
#! /bin/perl
# Forking out a series of processes which may take
# a while to run. System waits for any signal to be
# received back so that it can get the faster ones
# finalised quickly! Once a signal is received back
# it finds the appropriate pipe and reads from it
@waitlist = (3,2,1);
$SIG{USR1} = "doneit";
$start = localtime();
print "Started $start\n";
$parent = $$;
# Use a "typeglob" to store, in effect, a list of
# file handles.
foreach $item (@waitlist) {
pipe *{$item},FH;
unless ($pid = fork()) {
# Child process
sleep $item;
print FH "Completed $item\n";
kill "USR1",$parent;
print "I am finished... Process ",$item,"\n";
exit();
}
# Parent process - loop to start others
$kids++;
}
$mid = localtime();
print "Forked by $mid\n";
# Parent - wait for returned data
# To add - uses select to check channels!
while ($kids >0) {
while (! $gotone) {
sleep 1;
}
$gotone = 0;
foreach $item (@waitlist) {
$rin = $win = "";
vec($rin, fileno(*{$item}), 1) = 1;
$ein = $rin ;
$nfound=select($rin,$win,$ein,0);
print "Look:",$item," \$nfound:",$nfound,"\n";
if ($nfound) {
sysread($item,$response,40);
$now = localtime();
print "$now - $response";
close $item;
$kids--;
}
}
}
$end = localtime();
print "Completed $end\n";
sub doneit {
$gotone = 1;
}
can you tell me please what's happening here?
This piece of code is supposed to launch 3 children processes and to
keep track of each one when they finish.
THE PROBLEM: SOMETIMES (50% OF THE TIME) THE LAST PROCESS NEVER RETURNS
THE USR1 MESSAGE TO THE PARENT.
For example:
../fork3
Started Wed Jan 10 09:23:36 2007
Forked by Wed Jan 10 09:23:36 2007
I am finished... Process 1
Look:3 $nfound:0
Look:2 $nfound:0
Look:1 $nfound:1
Wed Jan 10 09:23:37 2007 - Completed 1
I am finished... Process 2
Look:3 $nfound:0
Look:2 $nfound:0
Look:1 $nfound:0
I am finished... Process 3
Look:3 $nfound:0
Look:2 $nfound:2
Wed Jan 10 09:23:39 2007 - Completed 2
Look:1 $nfound:0
And now the code:
#! /bin/perl
# Forking out a series of processes which may take
# a while to run. System waits for any signal to be
# received back so that it can get the faster ones
# finalised quickly! Once a signal is received back
# it finds the appropriate pipe and reads from it
@waitlist = (3,2,1);
$SIG{USR1} = "doneit";
$start = localtime();
print "Started $start\n";
$parent = $$;
# Use a "typeglob" to store, in effect, a list of
# file handles.
foreach $item (@waitlist) {
pipe *{$item},FH;
unless ($pid = fork()) {
# Child process
sleep $item;
print FH "Completed $item\n";
kill "USR1",$parent;
print "I am finished... Process ",$item,"\n";
exit();
}
# Parent process - loop to start others
$kids++;
}
$mid = localtime();
print "Forked by $mid\n";
# Parent - wait for returned data
# To add - uses select to check channels!
while ($kids >0) {
while (! $gotone) {
sleep 1;
}
$gotone = 0;
foreach $item (@waitlist) {
$rin = $win = "";
vec($rin, fileno(*{$item}), 1) = 1;
$ein = $rin ;
$nfound=select($rin,$win,$ein,0);
print "Look:",$item," \$nfound:",$nfound,"\n";
if ($nfound) {
sysread($item,$response,40);
$now = localtime();
print "$now - $response";
close $item;
$kids--;
}
}
}
$end = localtime();
print "Completed $end\n";
sub doneit {
$gotone = 1;
}