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):
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!
Dank Ihrer Prozessliste möchte ich Ihnen mitteilen, dass Sie auf eine der folgenden grundlegenden Einschränkungen stoßen:
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. 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.) /proc/sys/kernel/pid_max
. /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.
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%Tags und Links python fork subprocess spawn daemon