Helloe everyone,
I was wondering is someone can help me out with an issue with forking. I
am trying to fork 8 process at a time.
Here is what I have:
<code snippet>
#!/usr/bin/perl
use strict;
use warnings;
use lib ".";
use BACKUP; #my own module
use POSIX ":sys_wait_h";
my( $MAX_CHILDREN ) = "8";
my( $CHILD_PIDS ) = "0";
my( $maxtries ) = "7";
my( $failure ) = "0";
# there are actually 100 hostIds. but you should get the point..
my( @hostIds ) = "10.10.10.1, 10.10.10.2, 10.10.10.3 ,10.10.10.4";
$SIG{CHLD} = \&CHILD_COUNT($CHILD_PIDS);
FORK:
{
HOSTID: foreach my $hostId ( @hostIds ) {
redo HOSTID if $CHILD_PIDS >= $MAX_CHILDREN;
if( my $pid = fork ) {
$CHILD_PIDS++; #Add the children up until we hit the max
next;
}elsif (defined $pid) {
# In here I do some stuff with each $hostID.
# To make the code easier to read, I made a module that
# has a bunch of subroutines in it.
#There are basically 2 subroutines that I call for each
# hostID. 1 grabs the quota for each user on the hostId,
#The other tars and copies the user where the script
# is. I eval my connection and if some fails I
# go on to the next. ex.
until ( (BACKUP->QuotaIt( $hostId ) or ( $failures ==
$maxtries ) ) ) {
$failures++;
if ( $failures == $maxtries ) {
my( $subject ) = "Hey, WTF is up with $hosId";
my( $message ) = "$0 failed to connect to $hostID.";
BACKUP->MailIt( $subject, $message, $daily );
#go to the next hostid
next HOSTID2;
} #if statememt
} #until statement
}elsif($! =~ /No more process/){
sleep 15;
redo; #do over.
}else{
# this is just a mail routine that mails be that I
#can't fork
my( $subject ) = "Failed to fork any children";
my( $message ) = "$0 failed to fork anymore children.
BACKUP->MailIt( $subject, $message, $daily );
die;
}
} # foreach loop ends
} # this is the FORK
sub CHILD_COUNT {
my $child_pids = @_;
my $child = waitpid(-1,WNOHANG);
while ($child != -1 && ($child_pids > 0 )) {
$child_pids--;
$child = waitpid(-1,WNOHANG);
}
}
<end of code snippet>
Just typing this I realized that if I can't fork then I probably won't be
able to mail myself a notification. So I gotta change that else statement
with the mail notification.
Anyways, the issues I am having are two fold. The first I get this
warning:
Not a subroutine reference at ./script.pl line 331 which is:
" redo HOSTID2 if $CHILD_PIDS >= $MAX_CHILDREN;"
The second is a bigger issue. I also fork in the "home made" perl module
for each user of the HostId I am doing.
nothing crazy, just.........
#----------------------------------------------------------#
foreach $user (@users) {
my( $pid ) = fork ();
die "Cannot fork: $!" unless defined( $pid );
if ( $pid == 0 ) {
#do tarring of user
exit 0;
}
waitpid($pid,0);
}
#-----------------------------------------------------------#
Here I get the error:
Not a subroutine reference at BACKUP.pm line 195.
which is: " waitpid($pid,0);"
I know this is very confusing. And I might not even be posting to the right
list. But I am so frustrated with trying to get this thing to work. It
seems as if I have searched everywhere for examples of limiting the number of
forked processes, then being able to fork with in a fork.
I originally was using Parallel::ForkManager. But I found that if I set
the max_processes to 8 it will start eight but will not contiue until all
eight were done, then only do one at a time.
That's when I decided to go the POSIX route and use fork.. But just can't
get it working. I think setting the SIG{CHLD} is messing things up. BUt I
am not sure.
Sorry for being so drawn out. Please feel free to tear me/my code up. I am
new and would really like to know how to do this. Don't worry I can take
criticism pretty well... lol
Thanks in advance,
Chad
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]