2011-01-09 13 views
26

Byłem ciekawy, jak uruchomić skrypt w tle, powtarzając zadanie co 60 sekund. Wiem, że możesz umieścić coś w tle za pomocą &, czy to jest skuteczne dla tej sprawy?Efektywny demon Pythona

Myślałem o zrobieniu pętli, mając to czekać 60s i ładowanie go ponownie, ale coś o tym.

+1

To zależy od tego, co chcesz. Jeśli chcesz zaplanować powtarzanie zadania co jakiś czas, spójrz na crona. – Falmarri

Odpowiedz

7

Myślę, że twój pomysł jest dokładnie tym, czego potrzebujesz. Na przykład:

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

Połączenie z numerem time.sleep(60) spowoduje uśpienie programu na 60 sekund. Po upływie tego czasu system operacyjny obudzi Twój program i uruchomi funkcję do_something(), a następnie odłoży ją do trybu uśpienia. Podczas gdy twój program śpi, nie robi nic bardzo efektywnie. Jest to ogólny wzorzec do pisania usług w tle.

Aby rzeczywiście uruchomić z wiersza poleceń, można użyć &:

$ python background_test.py & 

Kiedy robi to każde wyjście ze skryptu trafi do tego samego terminala, jak ten, który rozpoczął się od. Możesz przekierować wyjście tego uniknąć:

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

Dzięki człowieku, właśnie tego szukałem. Fragmenty programowania, które znam, pochodzą z Javascript i próbują zrobić cokolwiek na zegarze, który zamienił się w koszmar! –

+1

Możesz także chcieć spojrzeć na nohup (np. 'Nohup python background_test.py') zakładając, że chcesz, aby demon działał po wylogowaniu) – Foon

+1

Jest to łatwiejszy sposób zrobienia tego przy użyciu' python-daemon' który jest "standardowa biblioteka procesów demonów": http://stackoverflow.com/a/8375012/462302 – aculich

5

Korzystanie & w powłoce jest prawdopodobnie martwy Najprostszym sposobem opisanym Greg.

Jeśli naprawdę chcesz stworzyć potężnego demona, musisz zajrzeć do polecenia os.fork().

Przykład z 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() 

A potem można umieścić cokolwiek zadanie potrzebne wewnątrz bloku doTask().

Nie trzeba uruchamiać tego przy użyciu &, a to pozwoliłoby na dalsze dostosowanie wykonania.

83

Zamiast pisać własnego demona, użyj zamiast niego python-daemon! python-daemon implementuje dobrze zachowaną specyfikację daemona pod nazwą PEP 3143, "Standardowa biblioteka procesów demonów".

Podałem przykładowy kod na podstawie przyjętej odpowiedzi na to pytanie i mimo że kod wygląda prawie identycznie, ma on istotną zasadniczą różnicę. Bez python-daemon musisz użyć &, aby umieścić swój proces w tle i nohup oraz aby Twój proces nie został zabity po wyjściu z powłoki. Zamiast tego automatycznie odłączy się od terminala po uruchomieniu programu.

Na przykład:

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

Aby faktycznie go uruchomić:

python background_test.py 

i zanotować brak & tutaj.

Ponadto, this other stackoverflow answer wyjaśnia szczegółowo wiele korzyści wynikających z używania python-daemon.

+1

Byłbyś zaskoczony, ale autor PEP i autor biblioteki to ta sama osoba. Więc tak, biblioteka bardzo dobrze realizuje to PEP :) – Reishin

+0

Mówisz "ta inna odpowiedź stackoverflow", ale link do pytania, a nie odpowiedź. Wybrana odpowiedź na pytanie, z którym się łączysz, nie używa (w czasie tego komentarza) python-daemon. Może masz na myśli https://stackoverflow.com/a/688448/117471? –

Powiązane problemy