windows python:相当于SIGALRM的windows
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8420422/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
python: windows equivalent of SIGALRM
提问by Claudiu
I have this decorator:
我有这个装饰器:
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
The code only does anything on linux, though, as on windows, there is no SIGALRM
. What would be the simplest way to have this code work in Windows as well?
该代码仅在 linux 上执行任何操作,但与在 Windows 上一样,没有SIGALRM
. 让这段代码也能在 Windows 中工作的最简单方法是什么?
采纳答案by Trey Stout
It's not very pretty, but I had to do something similar in a cross-platform way, and I came up with using a separate thread. Signal based systems did not work on all platforms reliably.
它不是很漂亮,但我必须以跨平台的方式做一些类似的事情,我想出了使用一个单独的线程。基于信号的系统并不能在所有平台上可靠地工作。
Use of this class could be wrapped up in a decorator, or made into a with
context handler.
此类的使用可以包含在装饰器中,或制成with
上下文处理程序。
YMMV.
天啊。
#!/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()
回答by JosiahYoder-deactive except..
I find this timeout-decorator code very handy, too. (I originally found it in this question answer: How to limit execution time of a function call in Python)
我也发现这个超时装饰器代码非常方便。(我最初是在这个问题答案中找到的:How to limit execution time of a function call in Python)
To make it work on Windows, I use the Python that is installed with Cygwin.
为了使其在 Windows 上运行,我使用了与 Cygwin 一起安装的 Python。
I run setup-x86_64.exe, then select the python3
package from the Python folder. (Or, if you prefer Python 2, the python
package.)
我运行 setup-x86_64.exe,然后python3
从 Python 文件夹中选择包。(或者,如果您更喜欢 Python 2,则使用该python
软件包。)
To rename python3 to python2, I define the alias
要将 python3 重命名为 python2,我定义了别名
alias python=python3
from the Cygwin command prompt. Since I don't use this functionality very often, I probably won't put it into a .bashrc or anything.
从 Cygwin 命令提示符。由于我不经常使用此功能,因此我可能不会将其放入 .bashrc 或任何其他文件中。
Related question: Python signal don't work even on Cygwin?