2016-05-13 2 views
0

в моем проекте python в таймере, который запускается «навсегда». вот код для таймера:Периодический таймер 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 питона «библиотеки»

Проблема в том, что кажется, что нить генерируется для каждого события таймера. Потому что, когда я получил 370 (это повторяемый) событие я получил ошибку:

Exception in thread Thread-370: Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner self.run() File "/usr/lib/python2.7/threading.py", line 1082, in run self.function(*self.args, **self.kwargs) File "Main.py", line 83, in _run self._timer.start() File "/usr/lib/python2.7/threading.py", line 745, in start _start_new_thread(self.__bootstrap,()) error: can't start new thread

Так что мой вопрос, как я могу быть уверен, что стрелять новое событие таймера только если предыдущее событие является закончить? или что-то в этом роде ...

-------------- FIRST EDIT -----------------

с первый комментарий от @JF Себастьян я использую это:

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 быть неисправным. Я делаю некоторые тесты без подключения/отключения каждый раз.

+0

Вам не нужно несколько потоков, чтобы вызывать функцию периодически, не блокируя основной поток. Вот пример кода, который использует один поток. (Http://stackoverflow.com/q/22498038/4279) – jfs

ответ

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() 
+0

спасибо за ваш подход, но я получил тот же результат: 'итерация: 241 активность: 2 раз: пт 13 май 16:01:40 +2016 FromEmit 1463155300.82 Exception в потоке Thread-241: Traceback (самый последний вызов последнего): Файл "/usr/lib/python2.7/threading.py", строка 810, в __bootstrap_inner» –

+0

Тогда есть проблема в библиотеке snap7 или с тем, как вы ее используете. Возможно, библиотека snap7 исчерпывает потоки системы. Отправьте наименьший пример, который показывает проблему. – ErikR

Смежные вопросы