Ask Your Question
0

Distinguish between alarm() and manual interrupt

asked 2012-04-22 12:03:03 +0100

chaesloc2 gravatar image

I have a long computation that needs to be repeated many times with different input. I want to limit each repetition to, say, a minute. Using alarm means that if I try to manually interrupt the whole thing, it will just assume that one repetition timed out. Is there a solution that doesn't involve restarting the worksheet?

while True:
    alarm(60)
    try:
        do_long_computation(random())
    except KeyboardInterrupt:
        continue
    alarm(0)
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2012-04-22 15:42:50 +0100

DSM gravatar image

updated 2014-01-27 17:21:47 +0100

Updated: modern Sage raises an AlarmInterrupt instead of a KeyboardInterrupt, so you can catch it explicitly instead. That's a much cleaner solution than having to dig around inside a KeyboardInterrupt message.

Also, it's probably a better idea to use cancel_alarm() than alarm(0), which was apparently never officially supported.


Sure. While I would have made it a little more explicit, the KeyboardInterrupt generated by alarm does contain information that a typical KeyboardInterrupt doesn't, in the .args and .message attributes. For example, control-C in the following

try:
    sleep(5)
except KeyboardInterrupt as KI:
    print 'args=',KI.args
    print 'message=', KI.message

produces

^Cargs= ()
message=

but adding alarm(2) before executing it produces:

args= ('computation timed out because alarm was set for 2 seconds',)
message= computation timed out because alarm was set for 2 seconds

So one way to take advantage of this would be through something like this:

while True:
    alarm(3)
    try:
        print 'sleeping..'
        sleep(5)
    except KeyboardInterrupt as KI:
        if KI.message.startswith("computation timed out"):
            print 'timed out!'
            continue
        else:
            # not a timeout, so break
            print 'manual exit!'
            alarm(0)
            break
    alarm(0)

which gives

sleeping..
timed out!
sleeping..
timed out!
sleeping..
timed out!
sleeping..
^Cmanual exit!

I tend to wrap this stuff up in decorators, but in this case mine is nested three deep so it's probably overkill for the problem, because it makes it look more complicated than it really is.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2012-04-22 12:03:03 +0100

Seen: 838 times

Last updated: Jan 27 '14