Demonio de Python eficiente

I was curious how you can run a python script in the background, repeating a task every 60 seconds. I know you can put something in the background using &, is that effeictive for this case?

I was thinking of doing a loop, having it wait 60s and loading it again, but something feels off about that.

preguntado el 09 de enero de 11 a las 02:01

It depends what you want. If you want to schedule a task to repeat every so often, take a look at cron. -

3 Respuestas

I think your idea is pretty much exactly what you want. For example:

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 la time.sleep(60) will put your program to sleep for 60 seconds. When that time is up, the OS will wake up your program and run the do_something() function, then put it back to sleep. While your program is sleeping, it is doing nothing very efficiently. This is a general pattern for writing background services.

To actually run this from the command line, you can use &:

$ python background_test.py &

When doing this, any output from the script will go to the same terminal as the one you started it from. You can redirect output to avoid this:

$ python background_test.py >stdout.txt 2>stderr.txt &

Respondido el 09 de enero de 11 a las 06:01

Thanks man, this is exactly what I was looking for. The bits and pieces of programming I know come from Javascript and trying to do anything on a timer there turned into a nightmare! - Kyle Hotchkiss

You may also want to look at nohup (e.g. nohup python background_test.py) assuming you want the daemon to keep running after you log out) - Foon

There is an easier way to do this using python-daemon which is the "standard daemon process library": stackoverflow.com/a/8375012/462302 - aculich

@user2452250: Please see the question ¿Qué if __name__ == “__main__”: ¿hacer? - Greg Hewgill

Rather than writing your own daemon, use Python-demonio ¡en lugar! Python-demonio implements the well-behaved daemon specification of PEP 3143, "Standard daemon process library".

I have included example code based on the accepted answer to this question, and even though the code looks almost identical, it has an important fundamental difference. Without Python-demonio tendrías que usar & to put your process in the background and nohup and to keep your process from getting killed when you exit your shell. Instead this will automatically detach from your terminal when you run the program.

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()

To actually run it:

python background_test.py

And note the absence of & aquí.

También, trabaja para esta otra respuesta de stackoverflow explains in detail the many benefits of using Python-demonio.

contestado el 23 de mayo de 17 a las 15:05

You would be surprised, but PEP author and library author is the same person. So yes, library very well implement that PEP :) - Reishin

You say "this other stackoverflow answer" but link to a question, not an answer. The selected answer to the question you link to does not use (at the time of this comment) python-daemon. Maybe you meant stackoverflow.com/a/688448/117471 ? - Bruno Bronosky

Using & in the shell is probably the dead simplest way as Greg described.

If you really want to create a powerful Daemon though, you will need to look into the os.fork() command.

The example from 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()

And then you could put whatever task you needed inside the doTask() bloquear.

You wouldn't need to launch this using &, and it would allow you to customize the execution a little further.

contestado el 18 de mayo de 16 a las 12:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.