D
darksaga
hi everybody,
i wrote a script where i use the fork command to speed up computation
of a program. the parent process spawns a limited number of children,
which process something. after a child process finishes its task a new
child is generated. this is repeated until the parent process reaches
the end of a file it runs through.
problem is that the fork command seems to mess up the parent filehandle
to my file, altough the children do not use this filehandle. when
looping through the file, the filehandle is magically reset to the
beginning of the file, or a position near the beginning. (see code
below)
i've read some other posts about the same prob. e.g.:
http://snipurl.com/s0pq
http://snipurl.com/s0ps
but there was no solution :/.
only thing was a workaround to read the file before forking into an
array, this solution is suboptimal for me coz my file could be >1GB.
sysnfo:
os: sun4u sparc 5.8
perl: v5.8.6 built for sun4-solaris
maybe there's someone out there, who knows a solution...
greets darksaga
____________________
#! /usr/bin/env perl -w
use strict;
use FileHandle;
my %children;
my $maxChildren = 10;
my $fileHandle = undef;
my $file = 'testFile';
createTestFile($file);
# start of main prog.
print "initial child spawning...\n";
for (1..$maxChildren)
{
if(my $line = getNextLine($file))
{
print "$line\n";
if(scalar(keys(%children)) < $maxChildren)
{
my $delay = int(rand 2)+1;
my $child = create_child($delay);
$children{$child} = "(slept $delay seconds)";
}
}
}
print "initial child spawning done...\n";
while(1) # loop until all done
{
my @pids = sort keys %children;
if (@pids)
{
#print "currently active children: @pids\n";
if(my $line = getNextLine($file))
{
print "$line\n";
if(scalar(keys(%children)) < $maxChildren)
{
my $delay = int(rand 2)+1;
my $child = create_child($delay);
$children{$child} = "(slept $delay seconds)";
}
}
}
else
{
print "all child processes are finished...\n";
}
if (($_ = wait) == -1)
{
print "wait() says no more children...\n";
last;
}
else
{
#print "child $_ has finished processing...". $children{$_} ."\n";
delete $children{$_};
}
}
print "parent is done...\n";
sub create_child
{
my ($delay) = @_;
my $pid = fork();
die "Unable to fork: $!" unless defined $pid;
return $pid if $pid; # Parent
child_routine($delay); # Child
die "Child $$ returned when it should have exited";
}
sub child_routine
{
my ($delay) = @_;
#print "Child $$ sleeping for $delay seconds\n";
sleep $delay;
#print "Child $$ exiting\n";
exit 0;
}
sub getNextLine
{
my ($fileName) = @_;
if (!$fileHandle)
{
$fileHandle = new FileHandle;
$fileHandle->open("< $fileName") or die $!;
}
my $entry = $fileHandle->getline();
unless($entry)
{
close $fileHandle;
return undef;
}
chomp($entry);
return $entry;
}
sub createTestFile
{
my ($fileName) = @_;
open(my $write, ">", "$file") or die $!;
for(1..30)
{
print $write "$_\n";
}
close $write;
}
i wrote a script where i use the fork command to speed up computation
of a program. the parent process spawns a limited number of children,
which process something. after a child process finishes its task a new
child is generated. this is repeated until the parent process reaches
the end of a file it runs through.
problem is that the fork command seems to mess up the parent filehandle
to my file, altough the children do not use this filehandle. when
looping through the file, the filehandle is magically reset to the
beginning of the file, or a position near the beginning. (see code
below)
i've read some other posts about the same prob. e.g.:
http://snipurl.com/s0pq
http://snipurl.com/s0ps
but there was no solution :/.
only thing was a workaround to read the file before forking into an
array, this solution is suboptimal for me coz my file could be >1GB.
sysnfo:
os: sun4u sparc 5.8
perl: v5.8.6 built for sun4-solaris
maybe there's someone out there, who knows a solution...
greets darksaga
____________________
#! /usr/bin/env perl -w
use strict;
use FileHandle;
my %children;
my $maxChildren = 10;
my $fileHandle = undef;
my $file = 'testFile';
createTestFile($file);
# start of main prog.
print "initial child spawning...\n";
for (1..$maxChildren)
{
if(my $line = getNextLine($file))
{
print "$line\n";
if(scalar(keys(%children)) < $maxChildren)
{
my $delay = int(rand 2)+1;
my $child = create_child($delay);
$children{$child} = "(slept $delay seconds)";
}
}
}
print "initial child spawning done...\n";
while(1) # loop until all done
{
my @pids = sort keys %children;
if (@pids)
{
#print "currently active children: @pids\n";
if(my $line = getNextLine($file))
{
print "$line\n";
if(scalar(keys(%children)) < $maxChildren)
{
my $delay = int(rand 2)+1;
my $child = create_child($delay);
$children{$child} = "(slept $delay seconds)";
}
}
}
else
{
print "all child processes are finished...\n";
}
if (($_ = wait) == -1)
{
print "wait() says no more children...\n";
last;
}
else
{
#print "child $_ has finished processing...". $children{$_} ."\n";
delete $children{$_};
}
}
print "parent is done...\n";
sub create_child
{
my ($delay) = @_;
my $pid = fork();
die "Unable to fork: $!" unless defined $pid;
return $pid if $pid; # Parent
child_routine($delay); # Child
die "Child $$ returned when it should have exited";
}
sub child_routine
{
my ($delay) = @_;
#print "Child $$ sleeping for $delay seconds\n";
sleep $delay;
#print "Child $$ exiting\n";
exit 0;
}
sub getNextLine
{
my ($fileName) = @_;
if (!$fileHandle)
{
$fileHandle = new FileHandle;
$fileHandle->open("< $fileName") or die $!;
}
my $entry = $fileHandle->getline();
unless($entry)
{
close $fileHandle;
return undef;
}
chomp($entry);
return $entry;
}
sub createTestFile
{
my ($fileName) = @_;
open(my $write, ">", "$file") or die $!;
for(1..30)
{
print $write "$_\n";
}
close $write;
}