Hi. I know this thread is almost 12 years old. I still want to clarify the presented problem for any possible new visitors searching for an answer on the subject.

Your previous code, the one that quits "unexpetedly", has issues, which I comment inline:

foreach $j (@j) { alarm 2; # ^ You shouldn't set an alarm out of the scope where you eval the + time out and localize $SIG{ALRM}; local $SIG{ALRM} = sub { die "timed out" }; # ^ This localization should be inside an eval block so you can ca +tch the alarm. eval { callfc() }; # ^ Here, you are only catching errors from your function, not fro +m a timeout next if $@ and $@ =~ /^timed out$/; # ^ You are checking for the exact string "timed out", but you sho +uld have /^timed out/ (without $ at the end), or, "timed out\n" in bo +th places (including the new-line character) because otherwise the me +ssage will include traces information from "die" }
Now, for your "working" code, which still has issues, I commend inline too:
foreach $j (@j) { print "Next Loop $j \n"; eval { local $SIG{ALRM} = sub { die "Alarm\n"; }; alarm(2); &callfc(); }; # ^ This is much better, you localize $SIG{ALRM} inside eval, and yo +u are also using # the new-line character in the message (and that's why it works (pa +rtially)) # In here, you should have called alarm(0) to cancel the alarm. # It doesn't matter if you are out of the eval block, the alarm cont +inues to run # and you eventually can have an uncatched "timeout" while being on +a different # part of your flow. You must call alarm(0) after your eval block (n +ot from inside # because it can die for a different cause too and never get to the +alarm(0) line). # So, I added it here: alarm 0; if ($@) { die unless $@ eq "Alarm\n"; # ^ You should send the error to the die too so you know what went + wrong, # like this: die $@ unless $@ eq "Alarm\n"; # But yes, you would catch a timeout here (if alarm 0 was present +too above). } else { print "Didnt\n"; } } print "I am continuing with the code\n"; # ^ Yeah... except if you didn't set alarm(0) above, and your script c +ontinues # to run and take longer than the alarm to complete, you'll eventually + have an # error stating "Terminating on signal SIGALRM(14)" and wonder why tha +t happened.
So, to summarize, this is what a timeout block should have, explained:
# First, the thing you want to timeout must be inside of an eval block +: eval { # Second, localize the signal handling and set alarm to the desired +timeout limit: $SIG{ALRM} = sub { die "timeout\n" }; alarm 10; # Third, add the lines of code you specifically want to timeout: do_something_here_that_can_timeout(); }; # Fourth: CANCEL the alarm immediately or you may have problems later! # This should be AFTER the eval block, not inside the eval block: alarm 0; # Fifth: Check for errors to see if you had a timeout or something els +e: if ($@ eq "timeout\n") { # Do whaever you need if a timeout happened handle_timeout(); } else { # You had an actual error and not a timeout, so handle it: handle_error($@); # or just: die $@ }
I hope this helps anyone trying to understand it.

- Zarabozo


In reply to Re^3: GOTO, Signals and Win32 by Zarabozo
in thread GOTO, Signals and Win32 by kakaze

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.