Замена signal.alarm в Windows [Python]

У меня есть функция, которая иногда зависает. Обычно я устанавливал будильник, но я в Windows, и он недоступен. Есть ли простой способ обойти это, или я должен просто создать поток, который вызывает time.sleep()?


Закончено с потоком. Только трюк использовал os._exit вместо 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

Ответы

Ответ 1

Наиболее надежным решением является использование подпроцесса, а затем уничтожение этого подпроцесса. Python2.6 добавляет .kill() в subprocess.Popen().

Я не думаю, что ваш подход к потоку работает так, как вы ожидаете. Удаление ссылки на объект Thread не приведет к уничтожению потока. Вместо этого вам нужно будет установить атрибут, который проверяет поток после его просыпания.

Ответ 2

Вы могли бы, как вы упомянули, просто начать новый поток, который спит в течение этого количества секунд.

Или вы можете использовать один из мультимедийных таймеров Windows (в Python, который будет в windll.winmm). Я считаю, что timeSetEvent - это то, что вы ищете. Кстати, я нашел фрагмент кода, который использует его здесь.

Ответ 3

Вот как оригинальный плакат решил свою собственную проблему:

Закончено с потоком. Только трюк использовал os._exit вместо 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