Code Comments
Programming Forum and web based access to our favorite programming groups.Hi Perlers,
I'm trying to check on the status of a process by sending a SIGZERO to
it with kill(). This SHOULD (according to the docs I've been reading)
return false if the process died. But mine is not. It always returns
true.
if( kill 0 => $pid ) {
print "the process is OK\n";
} else {
print "Something happened to the process: $!\n";
}
And for me, the above ALWAYS returns true. I'm wondering if this is
something to do with Solaris, and not Perl. Maybe this signal doesn't
behave the same way under Solaris?
Ok,
In the middle of writing this email I decided to write up a quick and
dirty test:
#!/usr/bin/perl
use warnings;
use strict;
my $pid = shift;
if( kill 0 => $pid ) {
print "Everything's ok\n";
} else {
print "$pid is not ok: $!\n";
}
When I run this code against a made up PID (I grep for it first to be
sure it's not really there), It works as expected, and:
17455 is not ok: No such process
is returned! That's good! that's what I want. but when I throw it
in my larger, longer Daemon script, it doesn't do it right. Just to
give some more explaination, My script daemonizes itself:
sub daemonize {
chdir '/' or die "Can't chdir to /: $!";
open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
open STDOUT, '/dev/null' or die "Can't write to /dev/null: $!";
defined( my $pid = fork ) or die "Can't fork the monitor: $!";
exit if $pid;
setsid or die "Can't start a new session: $!";
open STDERR, '>&STDOUT' or die "Can't dup STDOUT: $!";
}
then, It starts a bunch of children, capturing all of their process ID
in a hash:
sub start_servers {
my $cmdName = shift;
defined( my $pid = fork ) or die "Can't fork the server $cmdName: $!";
if( $pid == 0 ) { # Child
chdir '/' or die "Can't chdir to /: $!";
open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
open STDOUT, '/dev/null' or die "Can't write to /dev/null: $!";
setsid or die "Can't start a new session: $!";
open STDERR, '>&STDOUT' or die "Can't dup STDOUT: $!";
exec( $cmdName );
} else { # Parent
$children{$pid} = "$cmdName";
}
}
Then, the original goes into a loop, checking the children and (for
debug purposes at the moment) just prints some status:
do {
foreach( keys %children ) {
if( kill 0 => $_ ) {
print " - $_: $children{$_} is still ok.\n";
} else {
print " * $_: $children{$_} is not responding: $!\n";
}
}
sleep 5;
} while( 1 );
But ... I always get back the TRUE response, "- 17455: ./dummy_script
is still ok.". Did I miss something?
--Errin
Post Follow-up to this messageErrin Larsen wrote:
> Hi Perlers,
>=20
<snip>
>=20
> if( kill 0 =3D> $pid ) {
>
<snip>
Forgive me if I presume too much, but shouldn't the above be:
if( kill 0, $pid ) {
perldoc -f kill
Post Follow-up to this messageFrom: "Ed Christian" <edc@corp.ptd.net>
> Errin Larsen wrote:
>
> <snip>
>
>
> <snip>
>
> Forgive me if I presume too much, but shouldn't the above be:
>
> if( kill 0, $pid ) {
Those two are equivalent.
perl -MO=Deparse -e "kill 0 => $pid"
prints
kill 0, $pid;
-e syntax OK
just like
perl -MO=Deparse -e "kill 0, $pid"
Jenda
===== Jenda@Krynicky.cz === http://Jenda.Krynicky.cz =====
When it comes to wine, women and song, wizards are allowed
to get drunk and croon as much as they like.
-- Terry Pratchett in Sourcery
Post Follow-up to this messageOn Fri, 24 Sep 2004 10:31:36 -0400, Ed Christian <edc@corp.ptd.net> wrote:
> Errin Larsen wrote:
>
> <snip>
>
>
> <snip>
>
> Forgive me if I presume too much, but shouldn't the above be:
>
> if( kill 0, $pid ) {
>
> perldoc -f kill
>
Jenda is correct. I like to think of '=>' as "The FANCY comma!!".
It's just a pretty way of typing a comma for just such an occasion
when you want you code to reflect what you're doing. So, in the
above, I'm sending a signal to $pid, so the big arrow "shows" that the
signal (0) is being sent to that process ($pid)! Perl is Fun!!!
This works great (and is seen most often) in hash declarations:
my %demo_hash = (
Key_One => 1,
Key_Two => 2,
Key_Three => 3
);
Post Follow-up to this messageErrin Larsen wrote: > On Fri, 24 Sep 2004 10:31:36 -0400, Ed Christian <edc@corp.ptd.net> > wrote:=20 >=20 > Jenda is correct. I like to think of '=3D>' as "The FANCY comma!!". > It's just a pretty way of typing a comma for just such an occasion > when you want you code to reflect what you're doing. So, in the > above, I'm sending a signal to $pid, so the big arrow "shows" that > the signal (0) is being sent to that process ($pid)! Perl is Fun!!!=20 >=20 > This works great (and is seen most often) in hash declarations: >=20 > my %demo_hash =3D ( > Key_One =3D> 1, > Key_Two =3D> 2, > Key_Three =3D> 3 > ); I stand corrected. Sorry it wasn't an easy solution. :)
Post Follow-up to this messageOk, I learned something else ... When I type: kill -9 <SOME_PROCESS_ID> on the command line, It's not actually killing the process. Let me explain. My script starts 3 others and then stays around watching them. So, when I run it, I get this: # ps -ef | grep dummy user1 18000 1 0 10:04:22 ? 0:00 dummy_monitor user1 18001 18000 0 10:04:22 ? 0:00 dummy1 user1 18002 18000 0 10:04:22 ? 0:00 dummy2 user1 18003 18000 0 10:04:22 ? 0:00 dummy3 (the names have been changed to protect the innocent!) Now ... After I run a kill: # kill -9 18002 # ps -ef | grep dummy user1 18000 1 0 10:04:22 ? 0:00 dummy_monitor user1 18001 18000 0 10:04:22 ? 0:00 dummy1 user1 18003 18000 0 10:04:22 ? 0:00 dummy3 However, I just discovered that if I check the PID instead: # ps -ef | grep 18002 user1 180002 18000 0 0:00 <defunct> See that "<defunct>"?! How did my process get a <defunct> status? Is that a Solaris-fancy way of saying "zombie-child"? The above explains why my (kill 0 => $pid) isn't working the way I expect, but How can I kill the kid. The <defunct> child process finally dies if I kill the parent (original dummy_monitor) script. Does this mean that my setsid line in my original script is not working correctly? I'mhere. --Errin
Post Follow-up to this messageFrom: Errin Larsen <errinlarsen@gmail.com> > See that "<defunct>"?! How did my process get a <defunct> status? Is > that a Solaris-fancy way of saying "zombie-child"? I believe so. > The above explains > why my (kill 0 => $pid) isn't working the way I expect, but How can I > kill the kid. The <defunct> child process finally dies if I kill the > parent (original dummy_monitor) script. Does this mean that my setsid > line in my original script is not working correctly? I'm> here. I believe you are supposed to wait()/waitpid() on your children. Or install a $SIG{SIGCHLD} handler that reaps the children. I haven't used Perl under any Unix for years so I can't give you the details. perldoc perlipc should help. Jenda ===== Jenda@Krynicky.cz === http://Jenda.Krynicky.cz ===== When it comes to wine, women and song, wizards are allowed to get drunk and croon as much as they like. -- Terry Pratchett in Sourcery
Post Follow-up to this messageOn Fri, 24 Sep 2004 17:20:44 +0200, Jenda Krynicky <jenda@krynicky.cz> wrote:
> From: Errin Larsen <errinlarsen@gmail.com>
>
> I believe so.
>
>
> I believe you are supposed to wait()/waitpid() on your children. Or
> install a $SIG{SIGCHLD} handler that reaps the children.
>
> I haven't used Perl under any Unix for years so I can't give you the
> details. perldoc perlipc should help.
>
>
>
> Jenda
Yup. I tried putting:
$SIG{CHLD}='IGNORE';
in my parent and that prevents the zombie child. So, next question!
how do I wait() or waitpid() on more than one process? don't both of
those make the wait()ing process sit still and do nothing else until
it gets a return? I'll read perlipc again (man that's a hard one to
grok) and see what it says.
--Errin
Post Follow-up to this message> From: Errin Larsen <errinlarsen@gmail.com>
>
> I believe so.
I do as well.
>
>
> I believe you are supposed to wait()/waitpid() on your children. Or
> install a $SIG{SIGCHLD} handler that reaps the children.
>
That is what i was thinking. Essentially a process that has children
wants to hear from them (and will stop sending money if it doesn't).
Generally this is done by having the parent "wait" for the child until
it notifies the parent that it is gone, generally the parent knows that
when it doesn't have any more children it is done (or is to spawn more,
etc.).
> I haven't used Perl under any Unix for years so I can't give you the
> details. perldoc perlipc should help.
>
Yes, as well as,
perldoc -f wait
perldoc -f waitpid
> Jenda
http://danconia.org
Post Follow-up to this messageOn Fri, 24 Sep 2004 10:34:50 -0500, Errin Larsen <errinlarsen@gmail.com> wrote:
> On Fri, 24 Sep 2004 17:20:44 +0200, Jenda Krynicky <jenda@krynicky.cz> wro
te:
<<SNIP>>
>
> how do I wait() or waitpid() on more than one process? don't both of
> those make the wait()ing process sit still and do nothing else until
> it gets a return? I'll read perlipc again (man that's a hard one to
> grok) and see what it says.
>
> --Errin
>
Well, I found the following code snippet in perlipc:
sub REAPER {
my $child;
while( ( $child = waitpid( -1, WNOHANG ) ) > 0 ) {
$Kid_Status{$child} = $?;
}
$SIG{CHLD} = \&REAPER;
}
$SIG{CHLD} = \&REAPER;
This seems to do something similar to what I want, but I'm
about exactly what it's doing. what does the '-1' argument to
waitpid() do? What is the 'WNOHANG' flag? Why are we reassigning
'$SIG{CHLD}' to 'REAPER' inside of REAPER (this seems redundant to
me!)
I realize this is getting away from the "beginner" focus of this
mailing list, but I don't currently belong to any other mailing lists.
Thanks for any help you can throw at me.
--Errin
Post Follow-up to this message
Show a Printable Version
Email This Page to Someone!
Receive updates to this thread
Powered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.