hOURS am Sonntag, 3. Dezember 2006 03:25:
> "D. Bolliger" <[EMAIL PROTECTED]> wrote:  hOURS am Donnerstag, 30. November 
2006 21:09:
> > Jen Spinney  wrote:  On 11/20/06, hOURS  wrote:
> > >  Recently I posed a question on here regarding a program I have that
> > > runs other programs (through require statements and what not). My
> > > problem was that the programs getting run might have syntax errors and 
> > > I wanted to skip over each of those and go onto the next one. We 
> > > figured out a way to handle that. It turns out however, that these 
> > > programs sometimes have an even more troublesome problem: infinite 
> > > loops. I knew about this possibility, but figured I would just use the 
> > > time function, and if a program was taking to long, skip over it. Yeah,
> > >  that wasn't so smart. I can't have the main program check the elapsed 
> > > time while the required program is running its infinite loop. Or can I 
> > > somehow? Any ideas anybody? Thank you.
> > >         Fred Kittelmann
> >
> > Fred,
> > Have you checked out the alarm function?  I'm a beginner myself and I
> > had a similar problem earlier today.  alarm seemed to do it for me.
> > Good luck!
> >
> > - Jen
> >
> >   Thanks Jen,
> >   I've checked out alarm as much as I can.  My PERL textbook  scarcely
> > mentions it.  Trying "perldoc -f alarm" was a little more  informative,
> > but I still don't understand how to use this.  Can  anyone explain it to
> > me? Fred
>
> Does the following modified code example from 'perldoc -f alarm' helps?
>
> Dani
>
> #!/usr/bin/perl
> use strict;
> use warnings;
>
> my $timeout=5; # secs
>
> eval {
>   # Assign a signal handler subroutine which is invoked in case
>   # the alarm signal is sent
>   #
>   local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
>
>   # "send an alarm signal after $timeout seconds!"
>   #
>   alarm $timeout;
>
>   # to test a non-timeout die, uncomment following line:
>   #die;
>
>   # the problem:
>   #
>   endless_loop();
>
>   # reset alarm timer: "Don't send alarm signal any more"
>   #
>   alarm 0;
> };
>
> # Check if the code within eval died because of an alarm signal
> # or something else. We check the die message for that.
> #
> if ($@) {
>   if ($@ eq "alarm\n") {
>     warn "endless_loop() interrupted after timeout\n";
>   }
>   else {
>     warn "code in eval died!\n";
>     die;
>   }
> }
>
> warn "program continues...\n";
>
> sub endless_loop { {} while 1 }
>
> __END__

> Thanks, I suppose I understand that code example from 'perldoc -f alarm' a
> little better.  But much of it remains mysterious.  e.g. the very first
> thing within eval.  The only brackets I've ever seen with variables are []
> for list elements.  What's going on with {}?  

eval{} - see perldoc -f eval, it's the eval BLOCK variant.

$SIG{ALRM} - that's the way to retrieve the value with the 'ALRM' key from the 
hash %SIG; analogous to retrieve the $i'th value $array[$i] from an array 
@array. See perldoc perldata for the perl data types.
  NB: The '$' indicates the data type of the *accessed* data ($SIG{ALRM}, 
$array[$i]), and '[]' versus '{}' shows you if the "aggregated data 
structure" from which you take an element is a hash or an array.

There's another usage of {}:

my $x=1;
{ # make a scope block
  my $y=2;
}
# $y is no more defined outside the scope block above.

> And what a strange thing to 
> set a variable to - seems to be neither string nor number, but a
> subroutine?  

You refer to the line

  local $SIG{ALRM} = sub { die "alarm\n" }; 

?
Assigned is a so called "anonymous subroutine".
Above line could be reformulated by

  sub alarm_sburoutine { die "alarm\n" }; 
  local $SIG{ALRM} = \&alarm_subroutine;

But since the subroutine is only used once and is very short, the original 
line is an abbreviation.

see perldoc perlsub

> And why would you have a subroutine with just one line?  

Why not? 

sub a_sub_returning_one { 1 };
print 'the sub returns ', a_sub_returning_one;

Of course you could write it like

sub {
  die "alarm\n";
}

White space in the program code does not matter in *most* cases, unless in 
python for example.

> And  
> how can you have a subroutine without a name?  

See above, "anonymous subroutine" :-)

> And without a call to it?

It *is* called at the time the alarm timer reaches 0, although not explicitly 
from the code; 

See perldoc perlipc; it explains signals handlers at the top.

> Where is the thing being timed?  I understand something is being given 5
> seconds, but what?  Why is the variable $SIG{ALRM} not used again?

Hm... somebody else may explain this much better than I; 

alarm() is a form of IPC, using signals, and it is provided by the operating 
system. perls alarm() is just an interface to the operating systems alarm 
function. On *nix, see

man alarm
man signal

So it's timed "in the OS", given 5 secs, and the subroutine ("signal handler" 
in this context) is called from the OS internally.

> Is 
> there some significance to the name of that variable?

yes, %SIG is one of the special variables of perl, see the following document 
where all of them are described:

perldoc perlvar

> In 'perldoc -f 
> alarm' there's mention of a SIGALRM, but I don't know what that is.

Im fairly shure that there it is simply a short way to say "The ALRM signal".

> But I think we can ignore all those questions, because I don't see a need
> to work with this example.  I'm just looking for someone to tell me how
> alarm works.  A few sentences in English will be fine.  No code really need
> be written.

Ouch, I did not read the whole post before answering :-(

For the gory details of how it works on operating system / C level, somebody 
else has to take over - sorry

Dani

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to