Python Daemon-Prozess
Dieses Script kann als Grundlage für einen Daemon verwendet werden. Kurz zusammengefasst prüft
das Script mittels einer Lock-Datei ob der Daemon bereits läuft und startet ihn dann mittels einer double fork Methode um das Auftreten eines Zombie-Prozesses zu verhindern. Der Daemon-Prozess ist dann direkt ein Kind-Prozess von init und kann somit beim Beenden keinen Ärger mehr machen.
Übrigens ist dieses Script nur für UNIX-Systeme. Bei Windows werden Daemons Dienste genannt und funktionieren ganz anders.
Nähere Beschreibungen befinden sich im Quellcode.
Siehe auch os.fork, os.setsid und os.kill.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | #!/usr/bin/env python import sys, os, time import signal from datetime import datetime LOCKFILE="daemon.lock" def daemon(): """ Dummy fuer die Daemonfunktion. """ while True: f = open("test","w") f.write(str(datetime.now())) f.close() time.sleep(1) def write_pid( pid ): """ Schreibt die PID in die Lockfile. """ with open(LOCKFILE, "w") as f: f.write( str(pid) ) def read_pid(): """ Liest die PID aus der Lockfile und gibt sie zurueck falls der Prozess lauft. Wenn nicht gibt er 0 zurueck. """ try: with open(LOCKFILE) as f: try: pid = int( f.read() ) except ValueError: raise ValueError("Die Lockfile enthaelt keine PID.") if os.path.exists("/proc/{0}".format(pid)): return pid else: return 0 except IOError: return 0 # No such file def start(): """ Startet den Daemon, falls er nicht schon laeuft. Der Rueckgabewert ist True wenn der Daemon gestartet wurde und False wenn er bereits lauft. """ if read_pid(): return False # Der Prozess muss nun zwei Mal geforkt werden um einen Zombieprozess # zu verhindern. # Erster fork pid = os.fork() if pid != 0: os._exit(0) # beendet den Elternprozess os.setsid() # werde zum Sessionleiter # Zweiter fork pid = os.fork() if pid != 0: # Elternprozess write_pid(pid) # nun muss die Prozess ID gespeichert werden return True else: # Kindprozess # Hier wird die Daemonfunktion aufgerufen. Kann auch jede andere # Funktion sein. Macht natuerlich nur Sinn, wenn die Funktion in # einer Endlosschleife lauft. daemon() os._exit(0) def stop(): """ Stoppt den Daemon. """ pid = read_pid() if not pid: return False os.kill(pid, signal.SIGTERM) return True if __name__ == '__main__': try: cmd = sys.argv[1] except: cmd = None if cmd == 'start': start() sys.exit(0) elif cmd == 'stop': stop() sys.exit(0) elif cmd == "restart": stop() time.sleep(2) start() sys.exit(0) print "USAGE: daemon.py start|stop|restart" |
Kommentare
» Keine Kommentare vorhanden.