Unbestimmter Prozess der Daemonisierung von Prozessen in Python

8

Ich versuche einen Python-Daemon zu erstellen, der andere völlig unabhängige Prozesse startet.

Die allgemeine Idee ist, dass ein Shell-Befehl alle paar Sekunden abgefragt wird und sichergestellt wird, dass genau k Instanzen des Befehls ausgeführt werden. Wir behalten ein Verzeichnis von PID-Dateien, und wenn wir Polls abfragen, entfernen wir PID-Dateien, deren PIDs nicht mehr laufen und starten (und machen PID-Dateien für), aber viele Prozesse müssen wir zu k von ihnen bringen.

Die Kindprozesse müssen auch völlig unabhängig sein, so dass die Kinder nicht getötet werden, wenn der Elternprozess stirbt. Nach dem, was ich gelesen habe, scheint es keine Möglichkeit zu geben, dies mit dem Modul subprocess zu tun. Zu diesem Zweck habe ich das hier erwähnte Snippet verwendet:

Ссылка

Ich habe ein paar notwendige Änderungen vorgenommen (Sie werden sehen, dass die Zeilen im angehängten Snippet auskommentiert sind):

  1. Der ursprüngliche übergeordnete Prozess kann nicht beendet werden, da der Launcher-Daemon unbegrenzt persistent sein muss.
  2. Die untergeordneten Prozesse müssen mit dem gleichen CWD wie das übergeordnete Element beginnen.

Hier ist mein Spawn Fn und ein Test:

%Vor%

In dieser Situation scheinen die Dinge gut zu funktionieren, und die Kindprozesse bleiben bestehen, selbst wenn der Elternteil getötet wird. Allerdings stoße ich immer noch auf ein Spawn-Limit des ursprünglichen Elternteils. Nach ~ 650 Spawns (nicht gleichzeitig, die Kinder sind fertig) drosselt der Elternprozess mit dem Fehler:

%Vor%

Gibt es eine Möglichkeit, meine Spawn-Funktion neu zu schreiben, so dass ich diese unabhängigen Kindprozesse unbegrenzt spawnen kann? Danke!

    
Ryan N 08.12.2011, 01:40
quelle

2 Antworten

5

Dank Ihrer Prozessliste möchte ich Ihnen mitteilen, dass Sie auf eine der folgenden grundlegenden Einschränkungen stoßen:

  • rlimit nproc maximale Anzahl der Prozesse, die ein bestimmter Benutzer ausführen darf - siehe setrlimit(2) , bash(1) ulimit integriert und /etc/security/limits.conf für Details zu den Prozessgrenzen pro Benutzer.
  • rlimit nofile maximale Anzahl an Dateideskriptoren, die ein bestimmter Prozess auf einmal geöffnet haben darf. (Jeder neue Prozess erstellt wahrscheinlich drei neue Pipes in parent für die% descendens stdin , stdout und stderr des Kindes.)
  • Systemweite maximale Anzahl von Prozessen; siehe /proc/sys/kernel/pid_max .
  • Systemweite maximale Anzahl offener Dateien; siehe /proc/sys/fs/file-max .

Da Sie Ihre toten Kinder nicht ernten, werden viele dieser Ressourcen länger offen gehalten, als sie sollten. Ihre zweiten Kinder werden korrekt von init(8) behandelt - ihr Elternteil ist tot, also werden sie erneut nach init(8) und init(8) werden nach ihnen bereinigt ( wait(2) ) wenn sie sterben.

Ihr Programm ist jedoch verantwortlich für die Bereinigung nach dem ersten Satz von untergeordneten Elementen. C-Programme installieren in der Regel einen signal(7) -Handler für SIGCHLD , der wait(2) oder waitpid(2) aufruft, um den Beendigungsstatus der Kinder zu ernten und so seine Einträge aus dem Speicher des Kernels zu entfernen.

Aber die Signalverarbeitung in einem Skript ist ein bisschen nervig. Wenn Sie die Signalverteilung SIGCHLD explizit auf SIG_IGN setzen können, weiß der Kernel, dass Sie nicht am Exit-Status interessiert sind und erbt die untergeordneten Elemente für Sie _.

Fügen Sie Folgendes hinzu:

%Vor%

ganz oben in Ihrem Programm.

Beachten Sie, dass ich nicht weiß, was das für Subprocess bedeutet. Es könnte nicht zufrieden sein. Wenn dies der Fall ist, müssen Sie einen Signalhandler installieren , um anzurufen wait(2) für dich.

    
sarnold 08.12.2011, 02:32
quelle
3

Ich habe Ihren Code leicht modifiziert und konnte 5000 Prozesse ohne Probleme ausführen. Daher stimme ich @sarnold zu, dass du eine fundamentale Einschränkung gefunden hast. Meine Änderungen sind:

%Vor%     
ILYA Khlopotov 08.12.2011 02:00
quelle

Tags und Links