Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

fork and zombies

by Gangabass (Vicar)
on Oct 24, 2007 at 06:42 UTC ( [id://646834]=perlquestion: print w/replies, xml ) Need Help??

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

Hi, Monks!

I need your help again. My question is why i have zombies process when i run my program?

Zombies looks like so:

 3614 pts/1    D      0:00 /usr/bin/perl /root/USS/uss.pl
 3616 pts/1    D      0:00 /usr/bin/perl /root/USS/uss.pl
 3617 pts/1    Z      0:00 uss.pl <defunct>
 3618 pts/1    Z      0:00 uss.pl <defunct>
 3619 pts/1    Z      0:00 uss.pl <defunct>
 3620 pts/1    Z      0:00 uss.pl <defunct>
 3621 pts/1    D      0:00 /usr/bin/perl /root/USS/uss.pl

Here is part of program:

foreach my $row (@$sections) { if (my $pid = fork) { push @pids, $pid; } else { open BIDS, ">>", $CONFIG{BIDS_FOLDER} . "{currentsite}_" . $row->[ +0] . ".svd" or die "Could't open bids file!"; flock(BIDS, 2); print "$site_id, $row->[0], $row->[1]\n"; $found += search_bids( $site_id, $row->[0], $row->[1] ); flock(BIDS, 8); close BIDS; exit; } } for (my $i = 0; $i <= $#pids; $i++) { waitpid($pids[$i], 0); }

In search_bids sub i'm printing into BIDS and doing some LWP::UserAgent (getting pages and parse it) stuff.

Replies are listed 'Best First'.
Re: fork and zombies
by ikegami (Patriarch) on Oct 24, 2007 at 06:49 UTC

    It means the process has ended, but it hasn't been reaped (using waitpid) by its parent yet.

    The following code should reap the children as they end, instead of in the order they were created:

    foreach my $row (@$sections) { if (my $pid = fork) { $pids{$pid}++; } else { ... } } while (%pids) { my $pid = waitpid(-1, 0); delete $pids{$pid}; }

    By the way, have you considered Parallel::ForkManager? It seems ideal in this situation.

    Update: Added code.

      Thanks for Parallel::ForkManager. I'm mandatory look at it.

Re: fork and zombies
by Zaxo (Archbishop) on Oct 24, 2007 at 07:11 UTC

    waitpid looks for a particular child, and other signals may be lost. I like to keep the pid's as keys in a hash and delete them as they die:

    delete $pid{+wait} while %pid;
    Trying to do that in a for loop assumes that child processes will halt in a particular order.

    After Compline,
    Zaxo

Re: fork and zombies
by Somni (Friar) on Oct 24, 2007 at 06:51 UTC
    There's only one reason you ever get zombies: you were supposed to wait on a child process after it died, and you didn't. Given you're calling waitpid it means you either haven't gotten to that part of your code, or it's sitting there waiting on one pid that isn't ready.

    If you truly don't care what your child processes return, just set $SIG{CHLD} = "IGNORE". If you do care, then you should setup an actual signal handler, $SIG{CHLD} = sub { my $pid = wait; $exits{$pid} = $?; }, or something similar.

    Waiting on a specific pid is usually only done when you know that specific process has died.

    Also, foreach my $pid (@pids) { ... }, you don't need a C-style for loop to iterate over an array.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://646834]
Approved by Corion
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2024-04-24 18:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found