Reputation: 40224
I have a function that occasionally hangs.
Normally I would set an alarm, but I'm in Windows and it's unavailable.
Is there a simple way around this, or should I just create a thread that calls time.sleep()
?
Upvotes: 23
Views: 15337
Reputation: 900
I realize this thread has been inactive for some time, but I faced a similar issue and hope that someone else may find this useful as well.
As @jfs mentioned in a useful comment, the standard threading
module provides a Timer
method that works really well for this (docs). It is just a subclass of threading.Thread
, but it makes this very simple and clean. It can also be canceled using the inherited cancel
method.
import threading
delay_time = 3 # delay time in seconds
def watchdog():
print('Watchdog expired. Exiting...')
os._exit(1)
alarm = threading.Timer(delay_time, watchdog)
alarm.start()
my_potentially_never_ending_call()
alarm.cancel()
Upvotes: 5
Reputation: 78723
Here's how the original poster solved his own problem:
Ended up going with a thread. Only trick was using os._exit
instead of sys.exit
import os
import time
import threading
class Alarm (threading.Thread):
def __init__ (self, timeout):
threading.Thread.__init__ (self)
self.timeout = timeout
self.setDaemon (True)
def run (self):
time.sleep (self.timeout)
os._exit (1)
alarm = Alarm (4)
alarm.start ()
time.sleep (2)
del alarm
print 'yup'
alarm = Alarm (4)
alarm.start ()
time.sleep (8)
del alarm
print 'nope' # we don't make it this far
Upvotes: 3
Reputation: 339
The most robust solution is to use a subprocess, then kill that subprocess. Python2.6 adds .kill() to subprocess.Popen().
I don't think your threading approach works as you expect. Deleting your reference to the Thread object won't kill the thread. Instead, you'd need to set an attribute that the thread checks once it wakes up.
Upvotes: 3
Reputation: 8614
You could - as you mentioned - just kick off a new thread that sleeps for that number of seconds.
Or you can use one of Windows' multimedia timers (in Python, that'd be in windll.winmm). I believe timeSetEvent
is what you're looking for. Incidentally, I found a piece of code that uses it here.
Upvotes: 2