3

I'd like to do some computations in Python (actually in Sage, which is based on Python), but if they take longer than 10 seconds I want to cancel them. After looking at this SO thread about using the Python signal module for timeouts, I wrote the following code:

#!/my/path/to/sage

import time, signal

def handler(signum, frame):
    errortime = time.time()
    print str(errortime - starttime)[:7]
    raise Exception

signal.signal(signal.SIGALRM, handler)
signal.alarm(10)

# Try to do some long computations with Sage
starttime = time.time()
try:
    F.<a> = NumberField(x^31 -5*x^7 +6*x^6 +2*x^5 +4*x^4 +x^3 -3*x^2 -2*x +1)
    result = F.pari_nf()
except Exception:
    print "exception occurred"
finally:
    print result
    signal.alarm(0)

which, when run, prints the surprising result

18.1582
exception occurred

(and it really does take that amount of time, it's not just mismeasuring how long it took)

The computation in the try block does usually take about 18 seconds, but shouldn't the SIGALRM signal have been raised after 10 seconds, and errortime recorded then? Moreover shouldn't all attempts at doing the computation have stopped once an exception was encountered?

How can I make this Sage script actually stop what it's doing and exit if it takes longer than 10 seconds?

Community
  • 1
  • 1
Sal
  • 131
  • 3
  • 2
    It doesn't help with how to do this more reliably, but for why it isn't working see the docs you link, third dot point: "signals arriving during long calculations implemented purely in C ... may be delayed for an arbitrary amount of time". – lvc Feb 28 '15 at 11:03
  • @lvc: Ah, thanks for catching that - it does seem like that's what's going wrong. As an alternative, do you forsee any problems if I use the Linux command `timeout`, e.g. `timeout 10s ./script.sage`? As far as I can tell by running `top` afterwards, the script doesn't continue running, but I don't know whether there would be other harder-to-notice side effects. – Sal Feb 28 '15 at 11:10
  • [the `multiprocessing`-based solution from the thread that you've linked](http://stackoverflow.com/a/14924210/4279) could be used even if C extension does not return the control to Python interpreter e.g., by calling `PyErr_CheckSignals()` inside C loop. – jfs Feb 28 '15 at 13:09

0 Answers0