Подтвердить что ты не робот

Как выполнять функцию асинхронно каждые 60 секунд в Python?

Я хочу, чтобы функция выполнялась каждые 60 секунд на Python, но я не хочу, чтобы ее блокировали между тем.

Как я могу сделать это асинхронно?

import threading
import time

def f():
    print("hello world")
    threading.Timer(3, f).start()

if __name__ == '__main__':
    f()    
    time.sleep(20)

С помощью этого кода функция f выполняется каждые 3 секунды в течение 20 секунд времени. В конце он дает ошибку, и я думаю, что это потому, что threading.timer не был отменен.

Как я могу отменить его?

Спасибо заранее!

4b9b3361

Ответ 1

Вы можете попробовать класс threading.Timer: http://docs.python.org/library/threading.html#timer-objects.

import threading

def f(f_stop):
    # do something here ...
    if not f_stop.is_set():
        # call f() again in 60 seconds
        threading.Timer(60, f, [f_stop]).start()

f_stop = threading.Event()
# start calling f now and every 60 sec thereafter
f(f_stop)

# stop the thread when needed
#f_stop.set()

Ответ 2

Самый простой способ - создать фоновый поток, который запускает что-то каждые 60 секунд. Тривиальная реализация:

class BackgroundTimer(Thread):   
   def run(self):
      while 1:
        Time.sleep(60)
        # do something


# ... SNIP ...
# Inside your main thread
# ... SNIP ...

timer = BackgroundTimer()
timer.start()

Очевидно, что если "делать что-то" занимает много времени, вам нужно будет разместить его в своем заявлении сна. Но это служит хорошим приближением.

Ответ 3

Это зависит от того, что вы на самом деле хотите делать в среднее время. Темы являются наиболее общим и наименее предпочтительным способом его выполнения; вы должны знать о проблемах с потоковой обработкой при его использовании: не все (не-Python) коды допускают доступ из нескольких потоков одновременно, связь между потоками должна выполняться с использованием потокобезопасных структур данных, таких как Queue.Queue, вы не будете способный прерывать поток извне, и завершение программы, пока поток все еще работает, может привести к зависанию интерпретатора или ложных трассировок.

Часто есть более простой способ. Если вы делаете это в графической программе, используйте таймер или функциональность библиотеки графического интерфейса пользователя. У всех GUI есть это. Аналогично, если вы используете другую систему событий, такую ​​как Twisted или другая модель процесса сервера, вы должны иметь возможность подключаться к циклу основного события, чтобы заставить его регулярно вызывать вашу функцию. Подходы, не поддерживающие потоки, заставляют вашу программу блокироваться во время ожидания функции, но не между функциями.

Ответ 4

Я googled вокруг и нашел Python circuits Framework, что позволяет подождать для конкретного события.

Метод схем .callEvent(self, event, *channels) содержит функции пожара и приостановки до момента ответа, в документации говорится:

Опорожнить данное событие по указанным каналам и приостановить выполнение пока он не будет отправлен. Этот метод может быть вызван только как аргумент для yield на верхнем уровне выполнения обработчика (например, "yield self.callEvent(event)" ). Он эффективно создает и возвращает генератор, который будет вызываться основным контуром, пока событие не будет (см.: func: circuits.core.handlers.handler).

Надеюсь, вы сочтете это полезным, как я.

./regards

Ответ 5

Если вы хотите вызвать метод "на часах" (например, каждый час в часе), вы можете интегрировать следующую идею с любым выбранным механизмом нити:

import time

def wait(n):
    '''Wait until the next increment of n seconds'''
    x = time.time()
    time.sleep(n-(x%n))
    print time.asctime()

Ответ 6

Я думаю, что правильный способ повторного запуска потока следующий:

import threading
import time

def f():
    print("hello world")  # your code here
    myThread.run()

if __name__ == '__main__':
    myThread = threading.Timer(3, f)  # timer is set to 3 seconds
    myThread.start()
    time.sleep(10)  # it can be loop or other time consuming code here
    if myThread.is_alive():
        myThread.cancel()

С помощью этого кода функция f выполняется каждые 3 секунды в течение 10 секунд time.sleep(10). В конце отключение потока отменяется.

Ответ 7

Почему вы не создаете выделенный поток, в который вы помещаете простой спальный цикл:

#!/usr/bin/env python
import time
while True:
   # Your code here
   time.sleep(60)