Is there a better way to implement this:

M

Michael Yanowitz

Hello:

I wrote the code below (much irrelevant code removed).
This doesn't quite work. What I wanted it to do was
a) Execute function ftimed, which takes a function and a timeout
in seconds.
b) This will also execute function abort() as a thread.
This function just runs for the specified
number of seconds and returns.
However, before it returns, throws an exception.
c) If test() is still running when abort() is
finished, ftimed() should catch the exception and
return.

It is catching the exception, however it continues running the function.
Why does it continue and not return?

What am I missing, or is there a better way to
implement this (having ftimed() return when the
abort-timer time is exceeded?


import time, thread, sys

thread_finished = "MAX RUN TIME EXCEEDED!"

def abort (seconds):
start_time = time.time()
while ((time.time() - start_time) < seconds):
time.sleep(0.01)
print "script run time exceeded max_run_time of", seconds, "seconds."
raise thread_finished
return


def test():
i = 0
while (True):
time.sleep(1)
print "HELLO", i
i+=1


def ftimed (func, seconds):
thread.start_new_thread (abort, (seconds,))

try:
func()
except thread_finished:
print "Timeout"
return

ftimed (test, 30)
print "Script finished"

It presently generates the following output:
$ python ./testthread.py
HELLO 0
HELLO 1
HELLO 2
HELLO 3
HELLO 4
HELLO 5
HELLO 6
HELLO 7
HELLO 8
HELLO 9
HELLO 10
HELLO 11
HELLO 12
HELLO 13
HELLO 14
HELLO 15
HELLO 16
HELLO 17
HELLO 18
HELLO 19
HELLO 20
HELLO 21
HELLO 22
HELLO 23
HELLO 24
HELLO 25
HELLO 26
HELLO 27
HELLO 28
HELLO 29
script run time exceeded max_run_time of 30 seconds.
Unhandled exception in thread started by <function abort at 0x009CEF30>
Traceback (most recent call last):
File "./testthread.py", line 10, in abort
raise thread_finished
MAX RUN TIME EXCEEDED!
HELLO 30
HELLO 31
HELLO 32
.....



Thanks in advance:
Michael Yanowitz
 
B

Benjamin Niemann

Michael said:
Hello:

I wrote the code below (much irrelevant code removed).
This doesn't quite work. What I wanted it to do was
a) Execute function ftimed, which takes a function and a timeout
in seconds.
b) This will also execute function abort() as a thread.
This function just runs for the specified
number of seconds and returns.
However, before it returns, throws an exception.
c) If test() is still running when abort() is
finished, ftimed() should catch the exception and
return.

It is catching the exception, however it continues running the function.
Why does it continue and not return?

The exception is raised in the thread that executes the abort() function.
The exception does not get caught and terminates this thread. The other
(main) thread is unaffected - exceptions are local to a thread and there is
currently no (portable) way to raise an exception in another thread.
What am I missing, or is there a better way to
implement this (having ftimed() return when the
abort-timer time is exceeded?

You may use the signal.alarm() function, if you are on a UNIXoid system and
you have only a signle time-out at a time (e.g. not nested).
import time, thread, sys

thread_finished = "MAX RUN TIME EXCEEDED!"

def abort (seconds):
start_time = time.time()
while ((time.time() - start_time) < seconds):
time.sleep(0.01)

any reason for not using time.sleep(seconds) here?
 
P

Paul Boddie

Michael said:
I guess I am looking for something portable (both
Windows and Linux) where I can abort a function after
a certain time limit expires.

Doing a search for "timeout function Python" on Google reveals a number
of approaches.

Using signals:

* http://nick.vargish.org/clues/python-tricks.html
* http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/307871

Using threads:

* http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473878

Using processes:

* http://lfw.org/python/delegate.html

Paul
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,015
Latest member
AmbrosePal

Latest Threads

Top