eduffy
eduffy

Reputation: 40224

signal.alarm replacement in Windows [Python]

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

Answers (4)

Daniel Hill
Daniel Hill

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

LondonRob
LondonRob

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

Rhamphoryncus
Rhamphoryncus

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

FreeMemory
FreeMemory

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

Related Questions