Python周期性计时器生成太多线程

时间:2016-05-13 11:28:32

标签: python multithreading timer raspbian

在我的python项目中得到一个“永远”运行的计时器。 这是计时器的代码:

class MyTimer: 
    def __init__(self, tempo, target, args= [], kwargs={}): 
        self._target = target 
        self._args = args 
        self._kwargs = kwargs 
        self._tempo = tempo 

    def _run(self): 
        self._timer = threading.Timer(self._tempo, self._run) 
        self._timer.start() 
        self._target(*self._args, **self._kwargs) 
        if globalVar.Flag_Stop_Timer==100:
            self._timer.cancel() 

    def start(self): 
        self._timer = threading.Timer(self._tempo, self._run) 
        self._timer.start() 

    def stop(self): 
        self._timer.cancel() 

计时器调用的函数通过snap7 python“library”在PLC中读取数据

问题是似乎为每个计时器事件生成一个线程。 因为当我得到370(它是可重复的)事件时我得到了错误:

  

线程中的异常Thread-370:Traceback(最近一次调用最后一次):
  在__bootstrap_inner中输入文件“/usr/lib/python2.7/threading.py”,第810行       self.run()文件“/usr/lib/python2.7/threading.py”,第1082行,在运行中       self.function(* self.args,** self.kwargs)文件“Main.py”,第83行,在_run中       self._timer.start()文件“/usr/lib/python2.7/threading.py”,第745行,开头       _start_new_thread(self .__ bootstrap,())错误:无法启动新线程

所以我的问题是,只有在前一个事件结束后,我才能确定触发新的计时器事件?或类似的......

--------------第一次编辑-----------------

来自@ J.F的第一条评论。塞巴斯蒂安我用这个:

def call_repeatedly(interval, func, *args):
    stopped = Event()
    def loop():
        while not stopped.wait(interval): # the first call is in `interval` secs
            func(*args)
    Thread(target=loop).start()    
    return stopped.set

现在一切似乎都运作良好。现在它运行一个小时而不停止。 但是,虽然它没有因为我得到一个奇怪的行为之前的错误而崩溃。在运行5分钟内,断开时间比启动时多一秒。 正如@ErikR所说我开始问自己snap7-python是否有问题我每次都进行一些没有连接/断开连接的测试。

1 个答案:

答案 0 :(得分:0)

这种方法似乎没有泄漏任何线程。注意 - 在定期操作完成之前,这不会创建新的计时器。

#!/usr/bin/python

import time, threading

class MyPeriodic:
  def __init__(self):
    self.count = 0

  def start(self):
    self._timer = threading.Timer(1, self._run)
    self._timer.start()

  def stop(self):
    if self._timer:
      self._timer.cancel()
      self._timer = None

  def _run(self):
    self.stop()
    self.count += 1
    print "iteration:", self.count, "active:", threading.active_count(), "time:", time.ctime()
    self.start()