signal.alarm replacement in Windows [Python]

后端 未结 4 595
情深已故
情深已故 2020-12-03 20:53

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 sh

相关标签:
4条回答
  • 2020-12-03 21:44

    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.

    0 讨论(0)
  • 2020-12-03 21:44

    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.

    0 讨论(0)
  • 2020-12-03 21:49

    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()
    
    0 讨论(0)
  • 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
    
    0 讨论(0)
提交回复
热议问题