定期执行线程中的函数

时间:2015-04-20 01:38:51

标签: python python-multithreading

我找到了一个每隔N秒定期执行一次功能的解决方案。

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);

当我们执行此代码时,它会在执行时(时间= 0秒)开始打印“hello world”和“stackoverflow”。在不使用time.sleep

的情况下,打印时间= 1秒和时间= 0.5秒(不是在时间= 0秒开始)的可能方法是什么?

1 个答案:

答案 0 :(得分:1)

我真的很犹豫,每次都会产生一个新的TimerTimer扩展Thread,没有人想要每隔几秒钟启动一个新线程。

如果我们查看Python的源代码,我们可以为Timer类提供我们自己的实现。我不懂Python,所以可能有一种扩展类的方法,而不是基本上复制它的所有代码。

Timer类使用Event(也在threading模块中)等待指定的时间。

import threading;
from threading import Thread;
from threading import Event;

#Extended from a class written by Itamar Shtull-Trauring
class MultiTimer(Thread):
    def __init__(self, interval, function, count = 0, args=None, kwargs=None):
        Thread.__init__(self)
        self.interval = interval
        self.function = function
        self.args = args if args is not None else []
        self.kwargs = kwargs if kwargs is not None else {}
        self.finished = Event()
        self.count = count
        self.infinite = count == 0

    def cancel(self):
        """Stop the timer if it hasn't finished yet."""
        self.finished.set()

    def run(self):
        while not self.finished.is_set():
            self.finished.wait(self.interval)
            if not self.finished.is_set():
                self.function(*self.args, **self.kwargs)
                self.decrementCount()

    def decrementCount(self):
        if not self.infinite:
            self.count -= 1
            if self.count == 0:
                self.finished.set()

def hello():
    print "hello, world"

#prints "hello, world" 3 times, at time = 2, 4, 6
t = MultiTimer(2.0, hello, 3)
t.start();

#never stops printing "hello, world" every 2 seconds
u = MultiTimer(2.0, hello)
u.start();