I have a daemon that forks multiple child processes. I suspect something is going wrong over here, the reason being that the PIDs of the forked processes aren't getting generated in a sequential manner.
Please have a look at the code below:

#!/opt/perl-5.6.1/bin/perl ###################################################################### +########## ############ #Initial Phase: Make a working daemon. #Second Phase: Fork child processes. #Third phase: Build a basic framework wherein the individual pieces of + functionalities can be just plugged in. #Fourth Phase: Build the individual pieces of checks / other functiona +lities like debug option, logging other checks etc. #Fifth Phase: Bind the different functionalities with the basic framew +ork. #Sixth Phase: Test the compelete script. #Seventh Phase: Performance improvement. ###################################################################### +########## ############ use POSIX; use FileHandle; use File::Basename; use IO::Handle; #$PGM=basename($0); $DEF_TIMEOUT=60; $CHILD_TIMEOUT=10; $NUM_OF_KIDS=4; $shutitdown=0; #Please do not change this value. my $pid; my $file='/home/hkitmond/test.txt'; my $file2='/home/hkitmond/pid.txt'; my $logfile='/home/hkitmond/log'; STDOUT->autoflush(1); STDERR->autoflush(1); @jobs = (); %job = (); ###############Install signal handler############ $SIG{'TERM'}=$SIG{'INT'}=$SIG{'HUP'}=$SIG{'QUIT'}='shutdown'; ################################################# if ($pid=fork()){ print "\nI am the parent and just forked a child that has this PID:$pi +d"; #####Log this PID somewhere so that it can be used while issuing /bin/ +kill -s TERM <PID>############## open(PIDFILE, '>/home/hkitmond/pid.txt'); print PIDFILE "$pid"; close(PIDFILE); ###################################################################### +################################ print "\nExiting.."; exit 0; } elsif(!defined $pid){ print "\nCouldn't fork child. Probably process table is filled. Get in + touch with sysadm!!"; } else{ #This is the thread that is actually the daemon and it will keep runni +ng forever. setpgrp(0, 0); chdir('/'); print STDOUT "\nI am the child $$ and have just been forked by my pare +nt. Now I have become a daemon."; open(LOGFILE,'>/home/hkitmond/log'); LOGFILE->autoflush(1); while(1){ open(INPUT, $file)||die ("\nCannot open $file"); chomp (@args=<INPUT>); close(INPUT); $i=1; #if ($shutitdown==0){ #foreach $node (@args){ while ($node = shift(@args)){ if ($shutitdown==0){ $READER = "READER$i"; $WRITER = "WRITER$i"; pipe($READER, $WRITER); $WRITER->autoflush(1); if ($pid = fork()){ close($WRITER); $job{$pid}{'pipe'}= $READER; } elsif(!defined $pid){ print "\nCouldn't fork child"; } else{ ###This is the thread invoked per server - it will contain calls to wr +apper scripts for every check. Agent scripts reside on agent. ###This thread will exit after it runs checks and other tasks. ###################################### #Include timeout functionality here to make sure a thread doesn't ling +er too long. #Install the appropriate signal handler for timeout $SIG{'ALRM'}='thread_hung'; alarm $CHILD_TIMEOUT; print STDOUT "\nI am the child $$ corresponding to $node"; setpgrp(0, 0); close($READER); chdir('/'); ################################## #Write code here to call scripts to invoke various checks# #Use timeout functionality #while(1){ #} @RES = system("/usr/sbin/ping $node 3 > /dev/null"); ################################## $m="$$:$node:x_START_x"; print $WRITER "$m\n"; foreach $m (@RES){ print $WRITER "$m\n"; } close($WRITER); ###Exit this thread### exit 0; } ###################################################################### +########### #Need to implement logic to allow no more than defined number of threa +ds to run parallely #while(scalar(keys %job) >= $NUM_OF_KIDS || (%job && (scalar @args < $ +NUM_OF_KIDS))){ while(scalar(keys %job) >= $NUM_OF_KIDS || ((scalar(keys %job) >= 1) & +& (scalar @args == 0))){ print STDOUT "\n".scalar(keys %job).",".scalar @args; print STDOUT "\nWaiting for some child..."; $kpid= wait; #waiting for any child process to finish. This is essenti +al for proper termination of child. print STDOUT "\nJust waited for $kpid child"; #$a = @args; #not sure why this is added. next unless $job{$kpid}; #Not required actually. @kid_stdout = (); $PIPE=$job{$kpid}{'pipe'}; chomp(@kid_stdout=<$PIPE>); close($PIPE); foreach $l (@kid_stdout){ print STDOUT "\n$l"; print LOGFILE "\n$l"; } delete($job{$kpid}); #removing the element from job corresponding to +this process } ##Logic to restrict number of parallel threads less than the predefine +d value ends ###################################################################### +############## print STDOUT "\nGoing to next run of loop"; $i++; } #If block corresponding to $shutitdown=0 ends ###################################################################### +## #Need to include logic such that if a daemon needs to be killed, it ca +tches this signal, does the required cleanup and then exits. #If its req. to stop the daemon, use /bin/kill -9 <PID> command which +will be caught by signal handler and the required cleanup will be don +e. ###################################################################### +## else{ ############################################################## #This block contains logic such that on reception of SIGTERM, the alre +ady forked processes are waited upon by the parent. #We need to consider the situation where some child has already been k +illed as a result of timeout. ############################################################## print STDOUT "\nInside the cleanup section..."; print STDOUT "\nNumber of outstanding processes:".scalar(keys %job)." +.."; while(scalar(keys %job) != 0){ $pid=wait; delete($job{$pid}); print STDOUT "\nJust received exit status of $pid. Waiting for ".scala +r(keys %job)." others before stopping the daemon.."; } print "\nDaemon exiting..."; close(LOGFILE); exit 0; } #Else block corresponding to cleanup i.e. $shutitdown=1 ends } #for loop corresponding to every node from i/p file ends. =piyush ###################################################################### +## #Need to include logic such that if a daemon needs to be killed, it ca +tches this signal, does the required cleanup and then exits. #If its req. to stop the daemon, use /bin/kill -9 <PID> command which +will be caught by signal handler and the required cleanup will be don +e. ###################################################################### +## else{ ############################################################## #This block contains logic such that on reception of SIGTERM, the alre +ady forked processes are waited upon by the parent. #We need to consider the situation where some child has already been k +illed as a result of timeout. ############################################################## print STDOUT "\nInside the cleanup section..."; print STDOUT "\nNumber of outstanding processes:".scalar(keys %job)." +.."; while(scalar(keys %job) != 0){ $pid=wait; delete($job{$pid}); print STDOUT "\nJust received exit status of $pid. Waiting for ".scala +r(keys %job)." others before stopping the daemon.."; } print "\nDaemon exiting..."; exit 0; } #Else block corresponding to cleanup i.e. $shutitdown=1 ends =cut } #End of infinite while loop } #end of daemon code. ##############Subroutines Section##################################### +######## sub shutdown{ print STDOUT "\nReceived stop signal. Stopping the daemon..."; $shutitdown=1; } sub thread_hung{ print STDOUT "\nThread $$ is hung. Aborting.."; $id=$$; $pipe=$job{$id}{'pipe'}; delete($job{$id}); kill -9, $id; close($pipe); }



Here is a sample output:
I am the parent and just forked a child that has this PID:2040 I am the child 2040 and have just been forked by my parent. Now I have + become a daemon. Exiting..hkgisdev02% Going to next run of loop I am the child 2041 corresponding to abcd.pi.com I am the child 2042 corresponding to lonovoprod5.lehman.com Going to next run of loop I am the child 2046 corresponding to lonovoprod6.lehman.com/usr/sbin/p +ing: unknown host abcd.pi.com Going to next run of loop I am the child 2050 corresponding to lonlxvmopsw01.lehman.com 4,587 Waiting for some child... Just waited for 2041 child 2041:abcd.pi.com:x_START_x 256 Going to next run of loop I am the child 2052 corresponding to faicmc01-usrs07.lehman.com 4,586 Waiting for some child... Just waited for 2042 child 2042:lonovoprod5.lehman.com:x_START_x 0 Going to next run of loop 4,585 Waiting for some child... Just waited for 2046 child 2046:lonovoprod6.lehman.com:x_START_x 0 Going to next run of loop I am the child 2056 corresponding to lonintrelay2.lehman.com I am the child 2057 corresponding to losin11pudb4-m.lehman.com 4,584 Waiting for some child... Just waited for 2050 child 2050:lonlxvmopsw01.lehman.com:x_START_x 0 Going to next run of loop 4,583 Waiting for some child... I am the child 2062 corresponding to lonfwmgmt2.lehman.com Just waited for 2052 child 2052:faicmc01-usrs07.lehman.com:x_START_x 0


As can be seen in the above output, the PIDs that get generated are: 2041, 2042, 2046, 2050 and so on .... which is not in a sequence...
Can anyone see any potential flaw in the above code....?
Any help appreciated ...Thanks..

In reply to Is there any flaw with the way the below daemon forks child processes? by piyush

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.