python: windows equivalent of SIGALRM
我有这个装饰:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | def timed_out(timeout): def decorate(f): if not hasattr(signal,"SIGALRM"): return f def handler(signum, frame): raise TimedOutExc() @functools.wraps(f) def new_f(*args, **kwargs): old = signal.signal(signal.SIGALRM, handler) signal.alarm(timeout) try: result = f(*args, **kwargs) finally: signal.signal(signal.SIGALRM, old) signal.alarm(0) return result new_f.func_name = f.func_name return new_f return decorate |
但代码只能在linux上执行任何操作,因为在Windows上,没有
它不是很漂亮,但我必须以跨平台的方式做类似的事情,我想出了一个单独的线程。基于信号的系统无法可靠地在所有平台上运行。
使用此类可以包装在装饰器中,也可以组成
因人而异。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #!/usr/bin/env python2.7 import time, threading class Ticker(threading.Thread): """A very simple thread that merely blocks for :attr:`interval` and sets a :class:`threading.Event` when the :attr:`interval` has elapsed. It then waits for the caller to unset this event before looping again. Example use:: t = Ticker(1.0) # make a ticker t.start() # start the ticker in a new thread try: while t.evt.wait(): # hang out til the time has elapsed t.evt.clear() # tell the ticker to loop again print time.time(),"FIRING!" except: t.stop() # tell the thread to stop t.join() # wait til the thread actually dies """ # SIGALRM based timing proved to be unreliable on various python installs, # so we use a simple thread that blocks on sleep and sets a threading.Event # when the timer expires, it does this forever. def __init__(self, interval): super(Ticker, self).__init__() self.interval = interval self.evt = threading.Event() self.evt.clear() self.should_run = threading.Event() self.should_run.set() def stop(self): """Stop the this thread. You probably want to call :meth:`join` immediately afterwards """ self.should_run.clear() def consume(self): was_set = self.evt.is_set() if was_set: self.evt.clear() return was_set def run(self): """The internal main method of this thread. Block for :attr:`interval` seconds before setting :attr:`Ticker.evt` .. warning:: Do not call this directly! Instead call :meth:`start`. """ while self.should_run.is_set(): time.sleep(self.interval) self.evt.set() |
我发现这个超时装饰器代码也非常方便。 (我最初在这个问题答案中找到了它:如何在Python中限制函数调用的执行时间)
为了使它在Windows上运行,我使用与Cygwin一起安装的Python。
我运行setup-x86_64.exe,然后从Python文件夹中选择
要将python3重命名为python2,我定义了别名
1 | alias python=python3 |
从Cygwin命令提示符。由于我不经常使用此功能,我可能不会将它放入.bashrc或任何东西。
相关问题:
Python信号甚至在Cygwin上都不起作用?