Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re: Check if forked process is dead

by sundialsvc4 (Abbot)
on Mar 02, 2011 at 21:59 UTC ( [id://891112]=note: print w/replies, xml ) Need Help??


in reply to Check if forked process is dead

When you kill a process (in Unix), it enters a “zombie” state so that you can rendezvous with it (via waitpid) and collect its status.   You are obligated to do so.   The process-table entry does not disappear until you wait; hence, until then, it continues to “exist.”

Do not “pause for a specified interval” after killing a process.   After you have fired your bullet, wait for the corpse to hit the ground (and disappear).   No one likes a roomful of zombies.

Replies are listed 'Best First'.
Re^2: Check if forked process is dead
by petr999 (Acolyte) on Mar 02, 2011 at 22:20 UTC
    I'd like to know if I can check that process was not terminated by SIGTERM, so I'd SIGKILL it after some seconds. This doesn't work:
    $ perl -Mstrict -MPOSIX -wE 'my $pid = fork; if( $pid ){ kill TERM => +$pid; waitpid $pid => WNOHANG; say kill 0 => $pid; } else { sleep 3; + exit; }' 1 $
    But only 0 instead of WNOHANG shows me that process is ended.
    Can I check if the process is ended in a limited amount of time?
    Should I fork a new process only for a blocking waitpid $pid => 0 particularly?
    Thank you.

      You could inspect what the (non-blocking) waitpid returns. If it's the $pid, the process could be reaped successfully, which means it was no longer running.

      In your case here, you're calling the waitpid just a tad too early, so the preceding kill TERM hasn't been delivered/succeeded yet.  And as the waitpid $pid => WNOHANG couldn't yet reap at that moment, the process still exists as a zombie at the time you call kill 0  (like in your original case).

      Compare:

      Child reacts to SIGTERM:

      #!/usr/bin/perl -wl use strict; use POSIX; my $pid = fork; if ( $pid ) { kill TERM => $pid; # wait for kill TERM to take effect select undef, undef, undef, 0.01; my $reaped = waitpid $pid => WNOHANG; if ($reaped == $pid) { print "already gone."; # <--- } else { print "trying harder..."; kill 9 => $pid; } } else { sleep 3; }

      Child ignores SIGTERM:

      #!/usr/bin/perl -wl use strict; use POSIX; my $pid = fork; if ( $pid ) { # give child some time to set up its $SIG{TERM} handler select undef, undef, undef, 0.01; kill TERM => $pid; select undef, undef, undef, 0.01; my $reaped = waitpid $pid => WNOHANG; if ($reaped == $pid) { print "already gone."; } else { print "trying harder..."; # <--- kill 9 => $pid; } } else { $SIG{TERM} = 'IGNORE'; sleep 3; }
        Hello,
        Great!
        I believe too I can save a syscall with returning value from waitpid instead of kill 0 trial.
        Special thanks for show that I can use select instead of usleep(). Is it about any advantages, besides few typing and probably that Time::HiRes is not yet included in Perl-5.8 distribution?
        I think I'd better use some specialized CPAN Test::* module for just to build FCGI::Spawn tests... ;-)
        Peter Vereshagin <peter@vereshagin.org>

      You cannot avoid race conditions in such a quest ...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://891112]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2024-07-19 12:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.