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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 18:36:58  来源:igfitidea点击:

python: windows equivalent of SIGALRM

pythonwindowssignalsalarmsignal-handling

提问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 withcontext 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 python3package from the Python folder. (Or, if you prefer Python 2, the pythonpackage.)

我运行 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?

相关问题: Python 信号在 Cygwin 上也不起作用?