Как выполнять функцию асинхронно каждые 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 секунд time.time. В конце это дает ошибку, и я думаю, что это - потому что threading.timer не был отменен.

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

Заранее спасибо!

58
задан aF. 8 February 2010 в 17:36
поделиться

4 ответа

Вы можете попробовать класс 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()
100
ответ дан 24 November 2019 в 18:54
поделиться

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

Часто есть более простой способ. Если вы делаете это в программе с графическим интерфейсом, используйте функцию таймера или событий библиотеки графического интерфейса. Это есть во всех графических интерфейсах. Точно так же, если вы используете другую систему событий, например Twisted или другую модель серверного процесса, вы должны иметь возможность подключиться к главному циклу событий, чтобы заставить его регулярно вызывать вашу функцию. Непоточные подходы действительно приводят к тому, что ваша программа блокируется, пока функция ожидает, но не между вызовами функций.

2
ответ дан 24 November 2019 в 18:54
поделиться

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

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


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

timer = BackgroundTimer()
timer.start()

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

2
ответ дан 24 November 2019 в 18:54
поделиться

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

#!/usr/bin/env python
import time
while True:
   # Your code here
   time.sleep(60)
0
ответ дан 24 November 2019 в 18:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: