Zombies vermeiden

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
rhersel
User
Beiträge: 105
Registriert: Mittwoch 3. Dezember 2008, 11:29

Mein Python Programm erzeugt Zombies durch den Aufruf von suprocess.Popen() ohne .wait() weil ich nicht auf das Ende des Subprozesses warten kann. Da das Programm sehr lange läuft (theoretisch unendlich lange), werden die Zombies irgendwann einmal zum Problem (keine freien PIDs mehr da). Wie kann ich die Zombies im Programm killen?

Der Aufruf von subprocess.terminate() oder subprocess.kill() nachdem der Subprozess definitiv fertig ist (und zum Zombie wurde), funktioniert leider nicht. Auch nach dem subprocess.kill() existiert der Zombie immer noch. Wie werde ich die Biester los?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Wenn der Prozess sowieso terminiert ist, dann blokiert ``wait()`` nicht (merklich), somit kannst du die Werte der Kindprozesse entgegennehmen...
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
lunar

@rhersel: Zombies sind bereits beendete Prozesse, bei denen lediglich der Rückgabewert nicht durch den Vaterprozess ausgelesen wurde. Folglich kannst Du mit "terminate()" und "kill()" gar nichts ausrichten, denn einen beendeten Prozess kann man nicht "noch mehr" beenden. Deswegen heißen Zombies ja so.

Um Zombies zu vermeiden, musst Du entweder die Rückgabewerte der gestarteten Unterprozesse irgendwie auslesen, oder "init" zum Vaterprozess der gestarteten Prozesse machen.
rhersel
User
Beiträge: 105
Registriert: Mittwoch 3. Dezember 2008, 11:29

Ich kann nicht wait() verwenden, weilt die Subprozesse a, b, und c gleichzeitig loslaufen müssen und nicht einer nach dem anderen.

Wie kann ich denn die Rückgabewerte der gestarteten Unterprozesse auslesen?
lunar

@rhersel: Ist das nicht offensichtlich? Du legst die erzeugten "Popen"-Objekte einfach irgendwo in einer Liste ab, und gehst diese periodisch oder an zentraler Stelle durch, um mittels ".poll()" zu prüfen, ob der Prozess noch lebt. Falls nicht, liest das auch gleichzeitig den Rückgabewert aus, und Du kannst den toten Prozess guten Gewissens entfernen.

Die Alternative ist, "SIGCHLD" abzufangen, und in der Behandlungsfunktion "os.wait()" aufzurufen.
BlackJack

@rhersel: Die Rückgabewerte bekommt man mit `wait()`. Du sollst ja auch nicht Prozess `a` starten und dann darauf waren, und dann Prozess `b` starten und..., sondern `a`, `b`, und `c` starten und *dann* `wait()` verwenden. Irgendwo in Deinem Programm hast Du doch mal versucht `kill()` und `terminate()` auf Zombies anzuwenden -- an *der* Stelle wirst Du die mit `wait()` los.
rhersel
User
Beiträge: 105
Registriert: Mittwoch 3. Dezember 2008, 11:29

Vielen Dank.

Das mit dem subprocess.poll() habe ich ausprobiert und es funktioniert prima.

Die wait() Variante finde ich noch besser; muss ich mal testen.
Antworten