Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Signals in Strawberry Perl: Name or number?

by bv (Friar)
on Sep 12, 2009 at 19:03 UTC ( #794938=perlquestion: print w/ replies, xml ) Need Help??
bv has asked for the wisdom of the Perl Monks concerning the following question:

I was composing this perl poem and I ran into a strange issue with the kill command. I've only used it once before (Perl 5.10.0 on Ubuntu) and it worked fine, but this time, every time I try to kill ALRM, $$, the program quits. I tried kill 14, $$, same issue. I had set a signal handler for SIGALRM:

$SIG{ALRM} = sub { print "Alarming!\n"; };

...but it doesn't print. Any guesses as to what's going on here?

> perl -MConfig -e "print $Config{sig_name}" ZERO HUP INT QUIT ILL NUM05 NUM06 NUM07 FPE KILL NUM10 SEGV NUM12 PIPE + ALRM TERM NUM16 NUM17 NUM18 NUM19 CHLD BREAK ABRT STOP NUM24 CONT CLD
print pack("A25",pack("V*",map{1919242272+$_}(34481450,-49737472,6228,0,-285028276,6979,-1380265972)))

Comment on Signals in Strawberry Perl: Name or number?
Select or Download Code
Re: Signals in Strawberry Perl: Name or number?
by Anonymous Monk on Sep 12, 2009 at 19:25 UTC

      Unfortunately, that gives me an error:

      > perl -e "use POSIX 'SIGALRM'; die SIGALRM;' Your vendor has not defined POSIX macro SIGALRM, used at -e line 1

      On another note, though, I'm curious about that. Does die SIGALRM actually raise a SIGALRM to the calling process, similar to POSIX::raise? If so, is it a POSIX thing, or can I use die SIGSTOP and so forth without useing POSIX?

      print pack("A25",pack("V*",map{1919242272+$_}(34481450,-49737472,6228,0,-285028276,6979,-1380265972)))

        Does die SIGALRM actually raise a SIGALRM to the calling process

        No. die is a terse way of printing. It never sends a signal.

        I'm guessing SIGALRM is a constant whose value is the signal number associated with SIGALRM.

Re: Signals in Strawberry Perl: Name or number?
by Marshall (Prior) on Sep 12, 2009 at 23:19 UTC
    A "signal" is a way for your program to process "asynchronous" events. Meaning that you register a subroutine to be called when that event occurs. When you do this, you don't have to explictly keep checking that a particular event occured, the OS will call the sub when that event occurs.

    kill ALRM, $$ doesn't make sense to me!

    The below code shows a simple example of a handler for SIGALRM.

    #!/usr/bin/perl -w use strict; #$|=1; #see note below... $SIG{'ALRM'} = 'timeout'; alarm(1); while (1){sleep(1);} sub timeout { print "stdout: Alarming!\n"; print STDERR "stderr: Alarming!\n"; exit(0); }; __END__ prints: Note: stderr msg comes first because "autoflush" for stdout wasn't turned on (stdout normally doesn't get "flushed" until program end). $|=1; turns autoflush on. stderr: Alarming! stdout: Alarming!
    Kill $some_number makes no sense if $some_number is not a PID. kill ALRM doesn't have a PID. ALRM on my system is "numeric 14", but that is just shorthand for what the string ALRM means.
      kill ALRM, $$ doesn't make sense to me!

      It means "send an ALRM signal to the process with PID $$ (which mean the current process). While it may not make much sense in production code, it's certainly useful for testing.

      You may want to reread the docs for kill; unlike the shell version, the perl version requires you to have the signal as first parameter, followed by the PIDs you want to send the signal to.

        When I test code with ALRM signal, I fiddle with the alarm($num) parameter and often use sleep() to cause the alarm to "trigger" during testing. There are problems with signal handling...in general, there is no way to "safely" continue executing a process after an ALRM signal because many OS functions are not re-entrant or even re-startable by any means.

        Update: I strike this last sentence because it upset some folks. No offense was intended. I have no interest in obfuscated, obscure code although I do see that some folks have fun with this as an "art form".

        The original question was, why doesn't this code work?

        sub verse4 { my $boy; $SIG{ALRM} = sub { say "slip n slide" }; ride( $boy ), kill (ALRM, $$) for (1 .. 3); sleep 1; map { $_++ } ($ice_cream, $cake); } sub ride { say "Whee!" };
Re: Signals in Strawberry Perl: Name or number?
by afoken (Parson) on Sep 13, 2009 at 10:52 UTC

    Strawberry Perl runs on Windows. Windows does not have signals. POSIX systems like Linux have signals.

    Perl emulates some minor aspects of kill() on Windows, but you can't expect the emulation to be perfect.

    From perlport:

    kill() doesn't have the semantics of raise(), i.e. it doesn't send a signal to the identified process like it does on Unix platforms. Instead kill($sig, $pid) terminates the process identified by $pid, and makes it exit immediately with exit status $sig. As in Unix, if $sig is 0 and the specified process exists, it returns true without actually terminating it. (Win32)
    kill(-9, $pid) will terminate the process specified by $pid and recursively all child processes owned by it. This is different from the Unix semantics, where the signal will be delivered to all processes in the same process group as the process specified by $pid. (Win32)

    From perlwin32:

    Signal handling may not behave as on Unix platforms (where it doesn't exactly "behave", either :). For instance, calling die() or exit() from signal handlers will cause an exception, since most implementations of signal() on Win32 are severely crippled. Thus, signals may work only for simple things like setting a flag variable in the handler. Using signals under this port should currently be considered unsupported.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

      Thanks to everyone who has answered, and especially afoken for pointing me to a couple docs I hadn't read. Very helpful!

      print pack("A25",pack("V*",map{1919242272+$_}(34481450,-49737472,6228,0,-285028276,6979,-1380265972)))
Re: Signals in Strawberry Perl: Name or number?
by cdarke (Prior) on Sep 13, 2009 at 11:09 UTC
    This was my test code:
    #!/usr/bin/perl use strict; use warnings; $SIG{ALRM} = sub { print "Alarming!\n"; }; kill 'ALRM', $$; print "Not alarming\n";
    (The quotes around 'ALRM' required for strict).
    I don't have Strawberry Perl, but I tried it on ActiveState Perl 5.10.1 and got the same result, i.e. no output. I tried it on 5.10.0 on Cygwin and 5.8.8 on CentOS(Linux) and it worked correctly, i.e.
    Alarming! Not alarming
    On Windows and ActiveState perl, tracing shows that it does exit on the kill. I tried the same with an INT signal and that did not work either, however the symptoms were different. It did not execute the signal handler but it did not crash either.

    The ActiveState documentation says that alarm is not supported and signals are not properly supported anyhow. It's a Windows thing, but neither implementation should just drop-out without so much as a 'sorry'. The code is perfectly legal, if a bit of an edge case.
      On Windows XP, ActiveState 5.10 you will get:
      Process completed with exit code 14

      There is a problem with "kill", not with ALRM signal.

      And SIG INT works also!

      #!/usr/bin/perl use strict; use warnings; while (1) { sleep(1); } __END__ Terminating on signal SIGINT(2) Process completed with exit code 2
      ....This was CTRL-Break....

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (11)
As of 2014-10-23 17:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (126 votes), past polls