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

I had this pesk function that would take forever if it didn't work correctly, so I decided to set up a timer. The timer didn't work for some reason. I then set up this tiny progrom just to see if the alarm function was working right, and it didn't. I would be elated if someone could point out the flaw in my code. The code is below, followed by the error that it generated. __________________________________________________________
#!/usr/bin/perl -w eval{ $SIG{ALRM} = sub {die "DING-DING"}; alarm(10); print "I am frustrated."; alarm(0); }; if($@){ if ($@ eq "DING-DING"){ print "Yaaaaa!"; }else{ print "Uh oh, not an alarm error; here goes...\n $@ "; }}else{ print "No error was generated"; }
__________________________________________________________
Uh oh, not an alarm error; here goes... The Unsupported function alarm function is unimplemented at C:\p.pl line 4.

Replies are listed 'Best First'.
(bbfu) (alarm unsupported) Re: Problem with alarm()
by bbfu (Curate) on Oct 18, 2002 at 18:33 UTC

    ActiveState's Perl doesn't implement alarm. If the operation that may take a long time is going to be I/O based, you might want to look into select instead.

    bbfu
    Black flowers blossum
    Fearless on my breath

Re: Problem with alarm()
by dug (Chaplain) on Oct 18, 2002 at 18:39 UTC
    From perldoc perldiag:
    Unsupported function %s
      (F) This machine doesn’t implement the indicated function,     
      apparently.  At least, Configure doesn’t think so.
    

    Not a flaw in you code, you're using a flawed OS <grin>.

      dug
Re: Problem with alarm()
by fokat (Deacon) on Oct 19, 2002 at 03:38 UTC
    Actually, your code does have a bug. I think you wanted to do something along the lines of

    eval{ $SIG{ALRM} = sub {die "DING-DING"}; alarm(10); sleep(20); # <-- This line is missing print "I am frustrated."; alarm(0); };
    Otherwise, you're telling Perl to schedule an alarm() for ten seconds later, print the message and the cancel the alarm. Unless your machine is exceptionally slow, this would not work on *nix either because the print should take much less than 10 seconds, so the alarm gets cancelled.

    As a side note, it is a very good idea to try to keep your signal handlers small and simple. Perl's instructions are quite complex in terms of the processing involved.

    Signals (the result of an alarm, for example) can arrive at any point in time. In particular, they can arrive just in the middle of adding an entry to a hash. This has the potential to call your signal handler with a corrupt state in part of your program's data.

    With recent versions of Perl, this is less of an issue but I thought in throwing this piece of advice just in case.

    An alternative you can use, is what is sometimes called a post-file. Your expensive function can check periodically wether this file exists. If it does, it can abort itself gracefully. Just remember to remove the file when your program starts. The code to do this would be something along the lines of

    sub long_running_function { ... while ($your_condition) { ... return undef if -f $post_file; # Or die() if you want ... } } unlink $post_file; # May fail silently, but who cares? ... &long_running_function(); ...
    You can refine this technique and create the file when you enter the long_running_function() and then check its age periodically until it reaches a threshold, at which you bail out.

    Regards.

Re: Problem with alarm()
by particle (Vicar) on Oct 19, 2002 at 14:10 UTC

    if you're able to upgrade to perl 5.008, alarm is implemented on Win32. otherwise, you'll have to find an alternative. one such alternative is Win32::Event. there's an example of a problem and solution at ALRMing behavior on Win32

    ~Particle *accelerates*

Thanks for the help.
by Chris_Hayes (Initiate) on Oct 21, 2002 at 17:53 UTC
    Thanks