fdegir has asked for the wisdom of the Perl Monks concerning the following question:

I have 2 executables, execA and execB, which I run number of test cases against them. I created a simple script to execute 3 parallel child processes. execA runs fine. I run same script for execB and check the process tree, I see that 2 of the 3 child processes become defunct. Here is the script I'm having problems with. By the way, executables are basically same but execB has more number of test cases which I don't think make any difference.
my @childs; for ( my $count = 1; $count <= 4; $count++) { my $pid = fork(); if ($pid) { push(@childs, $pid); }elsif($pid == 0){ testExec($count); exit 0; }else{ die "couldnt fork: $!\n"; } } foreach (@childs) { my $tmp = waitpid($_, 0); print "done with pid $tmp\n"; } ######################## sub testExec($){ my $arg = shift; system("execB $arg"); }

Replies are listed 'Best First'.
Re: Dying child processes
by ikegami (Patriarch) on Mar 14, 2011 at 18:38 UTC

    I see that 2 of the 3 child processes become defunct.

    Since you wait for them in a specific order, that's entirely possible and not a problem. You will eventually reap them once the 3rd (1st, really) child finishes.

    You could reap them sooner using wait instead of waitpid if you think it is a problem.

    By the way, your die will never be reached. When $pid is undef to indicate an error, it is numerically equal to 0.

    By the way, you could call exec instead of system (which calls fork, exec and waitpid) in the child.

Re: Dying child processes
by GrandFather (Saint) on Mar 14, 2011 at 20:07 UTC
    for ( my $count = 1; $count <= 4; $count++) {

    is better written:

    for (1 .. 4) {

    which is not only shorter, but it is much clearer that there will be four iterations of the loop. Note that the original version of the loop is somewhat nasty because it doesn't conform with the convention in C/C++ style for loops of using a half open interval starting a 0 and using < instead of <=.

    True laziness is hard work
Re: Dying child processes
by Illuminatus (Curate) on Mar 14, 2011 at 19:43 UTC
    for ( my $count = 1; $count <= 4; $count++) {
    This will create 4 children, not 3. Since I have no idea what 'execA,execB' do, can't know if this is a problem.

    As ikegami pointed out, the behavior you describe is, in fact, expected given how you have written the code (unless all of the children terminate simultaneously). As he also points out, since you are using system and not exec, you are not technically waiting for your actual test programs. However, I can't see how this would change the behavior.

    I can't tell from your post whether you are implying that 'execB' is terminating abnormally or not. If this is the case, and execA is not terminating abnormally, then execB is doing something different than execA. Check the return of the system call, and maybe add some debug in execB to see where it is terminating

    fnord