daemonize - python-daemon example
Demonio de Python eficiente (3)
Creo que tu idea es casi exactamente lo que quieres. Por ejemplo:
import time
def do_something():
with open("/tmp/current_time.txt", "w") as f:
f.write("The time is now " + time.ctime())
def run():
while True:
time.sleep(60)
do_something()
if __name__ == "__main__":
run()
La llamada a time.sleep(60)
pondrá su programa a dormir durante 60 segundos. Cuando se do_something()
ese tiempo, el sistema operativo activará su programa y ejecutará la función do_something()
, luego la pondrá en suspensión. Mientras tu programa está durmiendo, no está haciendo nada de manera muy eficiente. Este es un patrón general para escribir servicios de fondo.
Para ejecutar esto desde la línea de comandos, puedes usar &:
$ python background_test.py &
Al hacer esto, cualquier salida de la secuencia de comandos irá al mismo terminal desde el que se inició. Puede redirigir la salida para evitar esto:
$ python background_test.py >stdout.txt 2>stderr.txt &
Tenía curiosidad por saber cómo ejecutar un script de Python en segundo plano, repitiendo una tarea cada 60 segundos. Sé que puedes poner algo en segundo plano usando &, ¿es eso tan efectivo para este caso?
Estaba pensando en hacer un bucle, esperar a los 60 y volver a cargarlo, pero algo se siente mal al respecto.
En lugar de escribir tu propio daemon, ¡usa python-daemon lugar! python-daemon implementa la especificación de daemon de buen comportamiento de PEP 3143 , "Biblioteca de procesos de daemon estándar".
He incluido un código de ejemplo basado en la respuesta aceptada a esta pregunta, y aunque el código parece casi idéntico, tiene una diferencia fundamental importante. Sin python-daemon , tendría que usar &
para poner su proceso en segundo plano y nohup
y evitar que su proceso se elimine al salir de su shell. En su lugar, esto se separará automáticamente de su terminal cuando ejecute el programa.
Por ejemplo:
import daemon
import time
def do_something():
while True:
with open("/tmp/current_time.txt", "w") as f:
f.write("The time is now " + time.ctime())
time.sleep(5)
def run():
with daemon.DaemonContext():
do_something()
if __name__ == "__main__":
run()
Para ejecutarlo realmente:
python background_test.py
Y note la ausencia de &
aquí.
Además, esta otra respuesta de explica en detalle los muchos beneficios de usar python-daemon .
Usar y en la cáscara es probablemente la forma más simple de morir como describió Greg.
Sin embargo, si realmente deseas crear un Daemon poderoso, deberás buscar en el comando os.fork ().
El ejemplo de Wikipedia :
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os, time
def createDaemon():
"""
This function create a service/Daemon that will execute a det. task
"""
try:
# Store the Fork PID
pid = os.fork()
if pid > 0:
print ''PID: %d'' % pid
os._exit(0)
except OSError, error:
print ''Unable to fork. Error: %d (%s)'' % (error.errno, error.strerror)
os._exit(1)
doTask()
def doTask():
"""
This function create a task that will be a daemon
"""
# Open the file in write mode
file = open(''/tmp/tarefa.log'', ''w'')
# Start the write
while True:
print >> file, time.ctime()
file.flush()
time.sleep(2)
# Close the file
file.close()
if __name__ == ''__main__'':
# Create the Daemon
createDaemon()
Y luego puedes poner cualquier tarea que necesites dentro del bloque doTask()
.
No tendría que iniciar este uso con &, y le permitiría personalizar un poco más la ejecución.