Timeout test hangs IDLE

A

Andreas Tawn

I'm trying to integrate the timeout function from here
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473878 into a
long running automation script and the following code causes IDLE after
20 or 30 iterations in countTest.

This is in 2.5, XP and there's no traceback.

Could someone point me at the user error?

Thanks in advance.


def countTest():
for i in xrange(10000000):
print i
return True

def timeout(func, args=(), kwargs={}, timeout_duration=1, default=None):
import threading
class InterruptableThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.result = None

def run(self):
try:
self.result = func(*args, **kwargs)
except:
self.result = default

it = InterruptableThread()
it.start()
it.join(timeout_duration)
if it.isAlive():
return default
else:
return it.result

def runTest():
timeout(countTest, timeout_duration=5)

if __name__ == "__main__":
runTest()
 
K

kyosohma

I'm trying to integrate the timeout function from herehttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473878into a
long running automation script and the following code causes IDLE after
20 or 30 iterations in countTest.

This is in 2.5, XP and there's no traceback.

Could someone point me at the user error?

Thanks in advance.

def countTest():
for i in xrange(10000000):
print i
return True

def timeout(func, args=(), kwargs={}, timeout_duration=1, default=None):
import threading
class InterruptableThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.result = None

def run(self):
try:
self.result = func(*args, **kwargs)
except:
self.result = default

it = InterruptableThread()
it.start()
it.join(timeout_duration)
if it.isAlive():
return default
else:
return it.result

def runTest():
timeout(countTest, timeout_duration=5)

if __name__ == "__main__":
runTest()

I'm confused. What does it cause IDLE to do? I tried running the
script and it ran fine. I killed it 17346 since I have no intention of
letting it tie up my work for your extraordinary large iteration
number.

I'm using Python 2.4 on Windows XP.

Mike
 
A

Andreas Tawn

herehttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/47
3878into a

I'm confused. What does it cause IDLE to do? I tried running the
script and it ran fine. I killed it 17346 since I have no intention of
letting it tie up my work for your extraordinary large iteration
number.

I'm using Python 2.4 on Windows XP.

Mike

Sorry, I need a better proof-reader.

When I run that code, the output gets to ~26 and then IDLE (or the
shell, I'm not sure which) hangs and there's zero CPU activity in the
pythonw.exe process.
 
A

Andreas Tawn

Sorry, I need a better proof-reader.

When I run that code, the output gets to ~26 and then IDLE (or the
shell, I'm not sure which) hangs and there's zero CPU activity in the
pythonw.exe process.

Also, I should say that the the idea is that the huge iteration should
timeout after 5 seconds. I only gave it a 10000000 range because I
didn't know how fast it would get through the loop. Perhaps you stopped
it before the timeout triggered?

Cheers,

Drea
 
K

kyosohma

Also, I should say that the the idea is that the huge iteration should
timeout after 5 seconds. I only gave it a 10000000 range because I
didn't know how fast it would get through the loop. Perhaps you stopped
it before the timeout triggered?

Cheers,

Drea

No...I ran it for at least 30-60 seconds. Making a thread stop on
command is a pain though.

This link taught me one way to do it, but I cannot vouch how will it
works as I've never aborted any of my threads:

http://wiki.wxpython.org/LongRunningTasks

Mike
 
A

Andreas Tawn

I once made a small app that used threads on IDLE.
There was a strange error when using 'print' & threads. When
what I printed filled the entire screen, instead of moving
all the text up, IDLE just hanged. Try running your code from
the shell instead, to see if the problem is in IDLE.

HTH,
Sergio

It looks like there's two issues here, an IDLE problem and a "me"
problem ;o)

I changed the countTest function to time.sleep(10) rather than a big
loop. When I run the script from the command line, the timeout triggers
properly after 5 seconds but the countTest function (running in a
seperate thread now) continues for the whole 10 seconds. This is the
"me" problem. I though that the timeout function would kill the
countTest thread, but it seems like it doesn't do that. Rather, the
timout just returns after 5 seconds with the message that the countTest
thread is still alive. I guess I need to set event flags so the
countTest function can end itself rather than trying to kill it from the
main thread?

When I run it from IDLE, everything runs correctly, but after the
countTest thread ends after 10 seconds, IDLE hangs as before. IDLE bug,
maybe?

Thanks for the help everyone.

The code looks like this now.

def countTest():# Succeeds from the command line, hangs in IDLE
import time
time.sleep(10)
return True

def timeout(func, args=(), kwargs={}, timeout_duration=1, default=None):
import threading
class InterruptableThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.result = None

def run(self):
try:
self.result = func(*args, **kwargs)
except:
self.result = default

it = InterruptableThread()
it.start()
it.join(timeout_duration)
if it.isAlive():
return default
else:
return it.result

def runTest():
timeout(countTest, timeout_duration=5)
print "finished"

if __name__ == "__main__":
runTest()
 
G

Gabriel Genellina

En Thu, 06 Dec 2007 08:03:49 -0300, Andreas Tawn
It looks like there's two issues here, an IDLE problem and a "me"
problem ;o)

I changed the countTest function to time.sleep(10) rather than a big
loop. When I run the script from the command line, the timeout triggers
properly after 5 seconds but the countTest function (running in a
seperate thread now) continues for the whole 10 seconds. This is the
"me" problem. I though that the timeout function would kill the
countTest thread, but it seems like it doesn't do that. Rather, the
timout just returns after 5 seconds with the message that the countTest
thread is still alive. I guess I need to set event flags so the
countTest function can end itself rather than trying to kill it from the
main thread?

It's not "your" problem, the cookbook recipe your code is based on should
make it clear: it does *not* kill the thread, it just returns to the
caller earlier (at most when the timeout elapses). The thread continues to
run (and consuming resources, of course).
If you actually want to stop a background task, the safest way would be
for the thread to test some condition periodically and gracefully stop
when requested. If that's not possible, and you have to forcibly kill a
running thread, there is a different recipe at
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496960 (follow the
link at the end for an updated version).
When I run it from IDLE, everything runs correctly, but after the
countTest thread ends after 10 seconds, IDLE hangs as before. IDLE bug,
maybe?

Not exactly; doing background tasks with a GUI is tricky and requires some
kind of cooperation, else the interfase usually becomes unresponsive.
How to run background tasks depends on the GUI toolkit used. IDLE uses
Tkinter, do you use that toolkit for your final program?
 

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

No members online now.

Forum statistics

Threads
473,955
Messages
2,570,117
Members
46,705
Latest member
v_darius

Latest Threads

Top