2011-01-09 15 views
26

Ich war neugierig, wie Sie ein Python-Skript im Hintergrund ausführen können, eine Aufgabe alle 60 Sekunden wiederholen. Ich weiß, dass Sie etwas in den Hintergrund setzen können mit &, ist das für diesen Fall wirksam?Effizienter Python-Daemon

Ich dachte daran, eine Schleife zu machen, sie 60 Sekunden warten zu lassen und sie wieder zu laden, aber etwas fühlt sich daran an.

+1

Es hängt davon ab, was Sie wollen. Wenn Sie eine Aufgabe so planen möchten, dass sie wiederholt ausgeführt wird, werfen Sie einen Blick auf cron. – Falmarri

Antwort

7

Ich denke, Ihre Idee ist ziemlich genau das, was Sie wollen. Zum Beispiel:

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

Der Aufruf von time.sleep(60) wird setzen Sie Ihr Programm für 60 Sekunden schlafen. Wenn diese Zeit abgelaufen ist, aktiviert das Betriebssystem Ihr Programm und führt die do_something()-Funktion aus und setzt es dann wieder in den Ruhezustand. Während Ihr Programm schläft, tut es nichts sehr effizient. Dies ist ein allgemeines Muster zum Schreiben von Hintergrunddiensten.

So führen diese tatsächlich aus der Befehlszeile Sie & verwenden können:

diese
$ python background_test.py & 

Wenn Dadurch wird bei jeder Ausgabe des Skripts gehen auf den gleichen Terminal wie die, die Sie es aus gestartet. Sie können die Ausgabe umleiten, dies zu vermeiden:

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

Danke Mann, das ist genau das, was ich gesucht habe. Die Teile der Programmierung, die ich kenne, kommen von Javascript und versuchen, irgendwas mit einem Timer zu machen, wurde dort zu einem Albtraum! –

+1

Sie können auch nohup (zB 'nohup python background_test.py') betrachten, vorausgesetzt, Sie möchten, dass der Daemon weiter läuft, nachdem Sie sich ausgeloggt haben) – Foon

+1

Es gibt einen einfacheren Weg dies mit' python-daemon' zu tun "standard daemon process library": http://stackoverflow.com/a/8375012/462302 – aculich

5

Mit & in der Schale ist wahrscheinlich die Toten einfachste Art und Weise, wie Greg beschrieben.

Wenn Sie jedoch wirklich einen leistungsfähigen Daemon erstellen möchten, müssen Sie sich den Befehl os.fork() ansehen.

Das Beispiel von 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() 

Und dann könnte man, was Aufgabe, die Sie innerhalb des doTask() Block benötigt setzen.

Sie müssten dies nicht mit & starten, und Sie könnten die Ausführung etwas weiter anpassen.

83

Anstatt einen eigenen Daemon zu schreiben, verwenden Sie stattdessen python-daemon! python-daemon implementiert die "brained" -Daemon-Spezifikation PEP 3143, "Standard-Daemon-Prozessbibliothek".

Ich habe Beispielcode basierend auf der akzeptierten Antwort auf diese Frage eingefügt, und obwohl der Code fast identisch aussieht, hat es einen wichtigen grundlegenden Unterschied. Ohne python-daemon müssten Sie & verwenden, um Ihren Prozess in den Hintergrund zu stellen und nohup und Ihren Prozess davon abzuhalten, getötet zu werden, wenn Sie Ihre Schale verlassen. Stattdessen wird diese automatisch von Ihrem Terminal getrennt, wenn Sie das Programm ausführen.

Zum Beispiel:

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

Um es tatsächlich auszuführen:

python background_test.py 

Und beachten Sie die Abwesenheit von & hier.

Auch this other stackoverflow answer erklärt im Detail die vielen Vorteile der Verwendung von python-daemon.

+1

Sie wären überrascht, aber PEP Autor und Bibliotheksautor ist die gleiche Person. Also ja, Bibliothek sehr gut implementieren, dass PEP :) – Reishin

+0

Sie sagen "diese anderen Stackoverflow-Antwort", sondern Link zu einer Frage, keine Antwort. Die ausgewählte Antwort auf die Frage, auf die Sie verlinken, verwendet (zum Zeitpunkt dieses Kommentars) nicht den Python-Daemon. Vielleicht meintest du https://stackoverflow.com/a/688448/117471? –