Seite 1 von 1

Doppel fork und zombie Problem

Verfasst: Dienstag 31. Juli 2018, 08:11
von Mazar
Hallo zusammen,

ich habe folgendes Problem, ich habe eine Funktion die die ganze Zeit einen Ordner beobachtet. Sobald etwas passiert wird ein fork ausgeführt und im Kindprozess der Rest abgearbeitet. während der Elternprozess weiter beobachtet. Das Problem hierbei ist, das die Kindprozesse immer als Zombies enden und ich diese nicht weg bekomme. Auch ein double fork bringt mich nicht weiter. Momenetan sieht es ungefähr so aus

Code: Alles auswählen

def child(filename):
	
	pid = os.getpid()
        time.sleep(5)
        sys.exit(0)


class MyHandler(FileSystemEventHandler):
    def on_created(self, event):
		if not event.is_directory:
			newpid = os.fork()
			if newpid == 0:
				os.setsid() # make it session leader
				os.umask(0)
				signal.signal(signal.SIGHUP, signal.SIG_IGN)	

				newpid = os.fork()
				if newpid == 0:
					signal.signal(signal.SIGHUP, signal.SIG_IGN)
					filepath, filename = os.path.split(event.src_path)
					child(filename)


Ich hänge hier echt und denke das ich hier einen Logikfehler habe.

Danke und Grüße

Re: Doppel fork und zombie Problem

Verfasst: Dienstag 31. Juli 2018, 08:49
von Sirius3
Hier fehlt auch noch, dass der erste fork-Prozess beenden wird und Du im Hauptprozess auf das Ende dieses Prozesses wartest.

Re: Doppel fork und zombie Problem

Verfasst: Dienstag 31. Juli 2018, 09:15
von Mazar
Das hatte ich auch schon versucht. Vielleicht stand es bei mir nicht an der richtigen Stelle, wie würde des dann in etwa aussehen?

Re: Doppel fork und zombie Problem

Verfasst: Dienstag 31. Juli 2018, 10:26
von __deets__
Es gibt doch schon fertige Pakete dafuer. daemonize oder so. Und warum muss denn daemonisiert werden, wenn du eh immer neue Prozesse startest? Da reicht doch ein simples subprocess, bzw. warum reicht das nicht?

Re: Doppel fork und zombie Problem

Verfasst: Dienstag 31. Juli 2018, 12:17
von Mazar
Also in dem Kindprozess werden Dokumente an den Drucker gesendet , log Einträge erstellt, Mails versendet usw. Ich weiß nicht ob ich das mit einem subprocess so hin bekomme. Ich stehe aber auch ehrlich gesagt gerade komplett auf dem Schlauch, ich habe schon so viele Varianten jetzt versucht aber die Kindprozesse enden immer als Zombies.

Re: Doppel fork und zombie Problem

Verfasst: Dienstag 31. Juli 2018, 12:31
von Sirius3
@__deets__: mit subprocess hast Du das selbe Problem mit den Zombies.

@Mazar: die Aufgaben hören sich auch eher danach an, als ob ein eigenes Programm der richtige Weg wäre.
Die Lösung des Zombieproblems ist es, in regelmäßigen Abständen zu schauen, ob die Kindprozesse inzwischen beendet sind. Das ist ja bei einer Dauerschleife, die auf Verzeichnisänderungen wartet, kein Problem. Auf diese Weise kann man auch prüfen, ob es im Kindprozess irgendwelche Fehler gab und dann entsprechend darauf reagieren.

Re: Doppel fork und zombie Problem

Verfasst: Dienstag 31. Juli 2018, 13:43
von Mazar
Also ich habe jetzt folgende Struktur
parent
child
grandchild

Ich bekomme jetzt auch das 2 fork welches die Logik ausführt komplett gelöscht habe aber nun weiter das Problem mit dem ersten child das dieses nun zu einem Zombie wird, also im Endeffekt das Gleiche. Selbst wenn ich das erste child ewig warten lasse und es kille während es läuft, wird es zu einem Zombie :/

Kleine Anmerkung, evtl gibt es dadurch ganz andere Lösungsansätze: Mir ist es nicht wichtig einen daemon zu erstellen sondern es ist mir wichtig einen neuen Prozess zu erzeugen der unabhängig vom parent läuft damit dieser weiter das Verzeichnis beobachten kann.

Re: Doppel fork und zombie Problem

Verfasst: Dienstag 31. Juli 2018, 14:19
von __deets__
@Sirius3: wieso habe ich mit subprocess das gleiche Problem? Da brauche ich ja ueberhaupt keinne Fork mehr, und subprocess kann "wait". Explizit oder implizit, wie der User es will.

@Mazar:

Code: Alles auswählen

class MyHandler(FileSystemEventHandler):
    def on_created(self, event):
		if not event.is_directory:
                       subprocess.call(["mein-kommando", event.path ]) # nur skizziert

Re: Doppel fork und zombie Problem

Verfasst: Dienstag 31. Juli 2018, 14:34
von __blackjack__
@__deets__: Aber das blockiert doch jetzt solange mein-kommando läuft. Wenn man dagegen `Popen` nimmt, muss man irgendwo ein `wait()` machen. Da ist dann die Frage wo man das einbaut bei was auch immer der OP hier verwendet.

Re: Doppel fork und zombie Problem

Verfasst: Dienstag 31. Juli 2018, 14:58
von Sirius3
@__deets__: Du brauchst kein fork mehr, weil das subprocess für Dich macht.

@Mazar: wie sieht Dein jetziger Code denn aus? Und wie schon geschrieben, kann es sehr nützlich sein, sich die Prozess-IDs zu merken und regelmäßig zu pollen.

Re: Doppel fork und zombie Problem

Verfasst: Dienstag 31. Juli 2018, 14:59
von Mazar
So also erst mal danke für die ganze Hilfe. Ich habe es jetzt folgend gelöst:

Code: Alles auswählen

class MyHandler(FileSystemEventHandler):
    def on_created(self, event):
		if not event.is_directory:
			newpid = os.fork()
			if newpid == 0: 
				os.setsid() 
				
				newpid = os.fork()
				if newpid == 0:
					filepath, filename = os.path.split(event.src_path)
					child(filename)
					os._exit(0)
				else:	
					os._exit(0)
			else:
				os.waitpid(newpid, 0)
So klappt es ganz gut. Der größte Fehler lag wohl daran das ich niergends wait genutzt hatte und durch 2 forks wird aauch der Elternprozess nicht blockiert.

Re: Doppel fork und zombie Problem

Verfasst: Dienstag 31. Juli 2018, 15:49
von __deets__
__blackjack__ hat geschrieben: Dienstag 31. Juli 2018, 14:34 @__deets__: Aber das blockiert doch jetzt solange mein-kommando läuft. Wenn man dagegen `Popen` nimmt, muss man irgendwo ein `wait()` machen. Da ist dann die Frage wo man das einbaut bei was auch immer der OP hier verwendet.
Voellig richtig, aber genau der Code der nach dem fork warten muss, muss dann halt auf einen Sack Popens warten. Wo ist da der Unterschied? Und bei subprocess kann man sich halt nicht verheddern.

Re: Doppel fork und zombie Problem

Verfasst: Dienstag 31. Juli 2018, 16:42
von __blackjack__
@__deets__: Bei dem double fork muss man doch nur kurz warten bis der geforkte Prozess seinerseits geforked hat und sich beendet. Das blockiert ja nur ganz kurz. Und der dann noch laufende Prozess hat keinen Elternprozess mehr und wird deshalb von init ”adoptiert” → wird nicht zum Zombie.

Re: Doppel fork und zombie Problem

Verfasst: Dienstag 31. Juli 2018, 17:17
von __deets__
Das ist sicher richtig, nur entstehen Zombies ja nur, wenn der Parent-Prozess noch lebt, aber nicht wartet. Wenn der also eine Liste von Kind-Prozessen verwaltet & dann "bewartet", dann ist alles gut. Und falls der Parent stirbt, erledigt der init das. Wie du ja selbst sagst. Es ist halt die Frage, ob man den semantisch immer ein bisschen ueberraschenden fork-Call einfuehrt, oder einen Mechanismus zum wait-aufruf via timer etc. Unixiger ist allerdings das fork, insofern: schoenere Loesung 👍

Re: Doppel fork und zombie Problem

Verfasst: Dienstag 31. Juli 2018, 17:33
von __blackjack__
@__deets__: Wenn man, wie Du ja vorgeschlagen hast, ein bereits existierendes Modul dafür nimmt, wird es IMHO noch schöner. :-)

Re: Doppel fork und zombie Problem

Verfasst: Dienstag 31. Juli 2018, 17:45
von __deets__
Wenn es den Use-Case hier unterstuetzt, das hab' ich nicht geprueft. Aber damit sollte dann ein externer Prozess ueber subprocess zB ja ebenfalls schnell zurueckkehren 🤔Da ist dann die Frage, welchen Zustand der Worker-Prozess alles braucht. Allerdings bin ich da eh eher fuer explizit statt implizit irgendwechen Prozesszustand anzunehmen, der nach dem geforke noch rumliegt...