make - ¿Cómo ejecutar una función de forma asíncrona cada 60 segundos en Python?
python asyncio tutorial (7)
Quiero ejecutar una función cada 60 segundos en Python, pero no quiero que me bloqueen mientras tanto.
¿Cómo puedo hacerlo de forma asíncrona?
import threading
import time
def f():
print("hello world")
threading.Timer(3, f).start()
if __name__ == ''__main__'':
f()
time.sleep(20)
Con este código, la función f se ejecuta cada 3 segundos dentro de los 20 segundos time.time. Al final da un error y creo que es porque el threading.timer no ha sido cancelado.
¿Cómo puedo cancelarlo?
¡Gracias por adelantado!
¿Por qué no creas un hilo dedicado, en el que pones un simple bucle para dormir?
#!/usr/bin/env python
import time
while True:
# Your code here
time.sleep(60)
Busqué en Google y encontré el framework de circuitos de Python, que hace posible esperar
para un evento en particular.
El método de circuitos .callEvent(self, event, *channels)
contiene una funcionalidad de disparo y suspensión hasta respuesta, la documentación dice:
Dispare el evento dado a los canales especificados y suspenda la ejecución hasta que se haya enviado. Este método solo se puede invocar como argumento para un
yield
en el nivel de ejecución superior de un controlador (por ejemplo, "yield self.callEvent(event)
"). Efectivamente crea y devuelve un generador que será invocado por el bucle principal hasta que el evento haya sido enviado (ver: func:circuits.core.handlers.handler
).
Espero que lo encuentres tan útil como yo :)
./Saludos
Creo que la forma correcta de ejecutar un hilo repetidamente es la siguiente:
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()
Con este código, la función f se ejecuta cada 3 segundos dentro de los 10 segundos time.sleep (10). Al final, la ejecución del hilo se cancela.
Depende de lo que realmente quieras hacer mientras tanto. Los hilos son la manera más general y menos preferida de hacerlo; debe tener en cuenta los problemas con el enhebrado cuando lo usa: no todos los códigos (que no son de Python) permiten el acceso desde múltiples hilos simultáneamente, la comunicación entre hilos debe hacerse usando estructuras de datos seguras de subprocesos como Queue.Queue
, no será capaz de interrumpir el hilo desde el exterior, y terminar el programa mientras el hilo aún se está ejecutando puede llevar a un intérprete colgado o trazas esporádicas.
A menudo hay una manera más fácil. Si está haciendo esto en un programa de GUI, use el temporizador de la GUI o la funcionalidad de eventos. Todas las GUI tienen esto. Del mismo modo, si está utilizando otro sistema de eventos, como Twisted u otro modelo de proceso de servidor, debería poder conectarse al bucle de evento principal para que llame a su función con regularidad. Los métodos sin enhebrar causan que su programa se bloquee mientras la función está pendiente, pero no entre llamadas de función.
La forma más sencilla es crear un hilo de fondo que ejecute algo cada 60 segundos. Una implementación trivial es:
class BackgroundTimer(Thread):
def run(self):
while 1:
Time.sleep(60)
# do something
# ... SNIP ...
# Inside your main thread
# ... SNIP ...
timer = BackgroundTimer()
timer.start()
Obviamente, esto si el "hacer algo" lleva mucho tiempo, tendrá que acomodarse en su declaración de sueño. Pero esto sirve como una buena aproximación.
Puede probar el subprocesamiento.Timer clase: 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()
Si desea invocar el método "en el reloj" (por ejemplo, cada hora en la hora ), puede integrar la siguiente idea con el mecanismo de enhebrado que elija:
import time
def wait(n):
''''''Wait until the next increment of n seconds''''''
x = time.time()
time.sleep(n-(x%n))
print time.asctime()