每隔N秒实时在线程中执行函数

时间:2012-07-15 02:17:18

标签: python multithreading real-time

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

的事情
do_stuff()
time.sleep(0.25)

但问题是没有考虑do_stuff()所需的时间。实际上,这需要是一个实时线程。有没有办法实现这个目标?理想情况下,线程在不执行代码时仍会处于休眠状态。

2 个答案:

答案 0 :(得分:39)

简单的解决方案

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)

答案 1 :(得分:2)

我用一个Thread做了一个不同的方法,在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()