Timing out arbitrary functions
dwahler at gmail.com
Sat Dec 24 18:13:33 CET 2005
Steven D'Aprano wrote:
> I have a problem and I don't know where to start looking for a solution.
> I have a class that needs to call an arbitrary function and wait for a
> result. The function, being completely arbitrary and not under my control,
> may be very time consuming and possibly may not even halt. My class needs
> to be able to give up waiting for a result after a specified amount of
> I'm thinking something conceptually like this:
> # pseudo-code:
> set time out to 30 seconds
> result = somefunction()
> except TimeOut:
> # 30 second time out happened
> print "somefunction() timed out without returning"
> print "somefunction() returned %s" % result
> The easy (for some definition of easy) solution would be to code
> somefunction() so that it raised an exception if it hadn't returned a
> result within a certain time. Unfortunately, I can't do rely on that -- I
> only have control over the calling code, not the called somefunction(),
> which may be any arbitrary function.
> How do others handle something like this? What should I be looking for?
> I'm after a lightweight solution, if any such thing exists.
For simple cases, I would use signal.alarm() with a SIGALARM handler
that raises a TimeOut exception. However, this is by no means
foolproof; you have to rely on the called function not to mess with
your signal handler. Plus, if your alarm occurs within a try-except
block that catches the TimeOut, it'll still be dropped. And to the best
of my knowledge, you can't otherwise forcibly terminate the execution
of a Python thread or block of code.
If you're going to be running untrusted code, I would use the
subprocess module to invoke a separate Python instance which takes the
code to be executed on stdin, and returns a pickled copy of the return
value on stdout. Then you can start it running, wait 30 seconds, and
then kill it if it hasn't already returned.
More information about the Python-list