Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

SIGZERO
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

Report this thread to moderator Post Follow-up to this message
Old Post
Errin Larsen
09-24-04 08:59 PM


RE: SIGZERO
Errin 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

Report this thread to moderator Post Follow-up to this message
Old Post
Ed Christian
09-24-04 08:59 PM


RE: SIGZERO
From: "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


Report this thread to moderator Post Follow-up to this message
Old Post
Jenda Krynicky
09-24-04 08:59 PM


Re: SIGZERO
On 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
);

Report this thread to moderator Post Follow-up to this message
Old Post
Errin Larsen
09-24-04 08:59 PM


RE: SIGZERO
Errin 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. :)

Report this thread to moderator Post Follow-up to this message
Old Post
Ed Christian
09-24-04 08:59 PM


Re: SIGZERO
Ok, 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'm 
here.

--Errin

Report this thread to moderator Post Follow-up to this message
Old Post
Errin Larsen
09-24-04 08:59 PM


Re: SIGZERO
From: 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


Report this thread to moderator Post Follow-up to this message
Old Post
Jenda Krynicky
09-24-04 08:59 PM


Re: SIGZERO
On 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

Report this thread to moderator Post Follow-up to this message
Old Post
Errin Larsen
09-24-04 08:59 PM


Re: SIGZERO
> 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

Report this thread to moderator Post Follow-up to this message
Old Post
Wiggins d Anconia
09-24-04 08:59 PM


Re: SIGZERO
On 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

Report this thread to moderator Post Follow-up to this message
Old Post
Errin Larsen
09-24-04 08:59 PM


Sponsored Links




Last Thread Next Thread Next
Pages (2): [1] 2 »
Search this forum -> 
Post New Thread

PERL Beginners archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 05:28 PM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.