Как создать фоновый поток на вызов функции интервала в python?

Я пытаюсь реализовать вызов heartbeat, который работает в фоновом режиме. Как создать поток с интервальным вызовом, скажем каждые 30 секунд, который вызывает следующую функцию:

self.mqConn.heartbeat_tick()

Также как бы остановить этот поток?

Большое спасибо.

+5
источник поделиться
4 ответа

Используйте поток, содержащий цикл

from threading import Thread
import time

def background_task():
    while not background_task.cancelled:
        self.mqConn.heartbeat_tick()
        time.sleep(30)
background_task.cancelled = False

t = Thread(target=background_task)
t.start()

background_task.cancelled = True

В качестве альтернативы вы можете использовать таймер подкласса, чтобы упростить отмену:

from threading import Timer

class RepeatingTimer(Timer):
    def run(self):
        while not self.finished.is_set():
            self.function(*self.args, **self.kwargs)
            self.finished.wait(self.interval)


t = RepeatingTimer(30.0, self.mqConn.heartbeat_tick)
t.start() # every 30 seconds, call heartbeat_tick

# later
t.cancel() # cancels execution
+6
источник

Одним из способов сделать это будет использование circuits рамок приложения следующим образом:

from circuits import Component, Event, Timer


class App(Component):

    def init(self, mqConn):
        self.mqConn = mqConn
        Timer(30, Event.create("heartbeat"), persist=True).register(self)

    def heartbeat(self):
        self.mqConn.heartbeat_tick()


App().run()

Примечание: я автор схем:)

Это всего лишь базовая идея и структура. Вам нужно будет адаптировать это решение в соответствии с вашими точными требованиями и требованиями!

+2
источник

Быстрый ответ на Eric ответ: вы не можете подклассом Timer, так как это фактически оболочка световой функции вокруг истинного класса: _Timer, Если вы это сделаете, вы получите сообщение об ошибке, которое появляется в этом сообщении.

Использование _Timer вместо этого исправляет его:

from threading import _Timer

class RepeatingTimer(_Timer):
    def run(self):
        while not self.finished.is_set():
            self.function(*self.args, **self.kwargs)
            self.finished.wait(self.interval)


t = RepeatingTimer(30.0, self.mqConn.heartbeat_tick)
t.start() # every 30 seconds, call heartbeat_tick

# later
t.cancel() # cancels execution
+2
источник

Или вы можете использовать класс Timer в модуле потоковой передачи:

from threading import Timer

def hello():
    print "hello, world"

t = Timer(30.0, hello)
t.start() # after 30 seconds, "hello, world" will be printed
t.cancel() # cancels execution, this only works before the 30 seconds is elapsed

Это не будет запускаться каждые x секунд, а это задерживает поток для выполнения за x секунд. Но вы можете поместить это в цикл и использовать t.is_alive(), чтобы увидеть его статус.

+1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос