【问题标题】:Periodically execute function in thread in real time, every N seconds [duplicate]每隔N秒在线程中实时定期执行函数[重复]
【发布时间】:2012-07-14 09:21:21
【问题描述】:

我有一个线程类,它的循环需要每秒执行 4 次。我知道我可以做类似的事情

do_stuff()
time.sleep(0.25)

但问题是它没有考虑到do_stuff() 所需的时间。实际上,这需要是一个实时线程。有没有办法做到这一点?理想情况下,线程在不执行代码时仍会进入睡眠状态。

【问题讨论】:

    标签: python multithreading real-time


    【解决方案1】:

    简单的解决方案

    import threading
    
    def work (): 
      threading.Timer(0.25, work).start ()
      print "stackoverflow"
    
    work ()
    

    以上将确保work 以每秒四次的间隔运行,其背后的理论是它会“排队”对自己的调用将运行0.25 秒后的未来,无需等待它发生。

    正因为如此,它可以(几乎)完全不间断地工作,并且我们非常接近每秒执行该函数 4 次。


    更多关于threading.Timer的信息可以通过下面的python文档链接阅读:


    推荐] 更高级/动态的解决方案

    即使之前的函数按预期工作,您也可以创建一个辅助函数来帮助处理未来的定时事件。

    对于这个例子来说,下面的内容就足够了,希望代码会自己说话——它并不像看起来那么先进。

    当您可以实现自己的包装器以满足您的确切需求时,将此视为灵感。

    import threading
    
    def do_every (interval, worker_func, iterations = 0):
      if iterations != 1:
        threading.Timer (
          interval,
          do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1]
        ).start ()
    
      worker_func ()
    
    def print_hw ():
      print "hello world"
    
    def print_so ():
      print "stackoverflow"
    
    
    # call print_so every second, 5 times total
    do_every (1, print_so, 5)
    
    # call print_hw two times per second, forever
    do_every (0.5, print_hw)
    

    【讨论】:

    • 看起来不错,但如何阻止呢?
    • 这个解决方案很好,但是我发现如果你需要做的工作比时间段长,你会过得很糟糕。为了停止这种情况,我建议等到之前的工作使用 Lock 对象完成。
    • 如果说 print_so 有参数 print_so(string1, string2),上面的包装代码将如何工作?我在一个有多个参数的函数上试过这个并得到一个 NoneType object is not callable 错误
    • 嘿,很棒的解决方案,这似乎每次都会执行两次给定的功能。我在烧瓶应用程序中使用它。我想知道这是否与它有关。
    【解决方案2】:

    我用一个线程做了一些不同的方法,在一个while循环中循环。 对我来说优势是:

    • 只有一个线程,这里提到的其他解决方案为每个间隔启动和停止线程
    • 对 Interval 的更多控制,您可以使用 .stop() 方法停止 IntervalTimer

    代码:

    from threading import Thread, Event
    
    # StoppableThread is from user Dolphin, from http://stackoverflow.com/questions/5849484/how-to-exit-a-multithreaded-program
    class StoppableThread(Thread):  
    
        def __init__(self):
            Thread.__init__(self)
            self.stop_event = Event()        
    
        def stop(self):
            if self.isAlive() == True:
                # set event to signal thread to terminate
                self.stop_event.set()
                # block calling thread until thread really has terminated
                self.join()
    
    class IntervalTimer(StoppableThread):
    
        def __init__(self, interval, worker_func):
            super().__init__()
            self._interval = interval
            self._worker_func = worker_func
    
        def run(self):
            while not self.stop_event.is_set():
                self._worker_func()
                sleep(self._interval)
    

    用法:

    def hw():
        print("Hello World")
    
    interval = IntervalTimer(1,hw)
    interval.start()
    
    sleep(10)
    
    interval.stop()
    

    【讨论】:

      猜你喜欢
      • 2018-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-15
      • 1970-01-01
      • 2018-11-05
      相关资源
      最近更新 更多