Как выполнять функцию асинхронно каждые 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 не был отменен.
Как я могу отменить его?
Спасибо заранее!
Ответы
Ответ 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)