python: windows equivalent of SIGALRM

后端 未结 2 1300
臣服心动
臣服心动 2020-11-27 22:20

I have this decorator:

def timed_out(timeout):
    def decorate(f):
        if not hasattr(signal, \"SIGALRM\"):
            return f

        def handler(si         


        
相关标签:
2条回答
  • 2020-11-27 22:43

    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)

    To make it work on Windows, I use the Python that is installed with Cygwin.

    I run setup-x86_64.exe, then select the python3 package from the Python folder. (Or, if you prefer Python 2, the python package.)

    To rename python3 to python2, I define the alias

    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.

    Related question: Python signal don't work even on Cygwin?

    0 讨论(0)
  • 2020-11-27 22:46

    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.

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