Gibt es eine Obergrenze für die Anzahl der Zombie-Prozesse, die Sie ausführen können?

17

Früher habe ich mit einem HP-UX-System gearbeitet, und der alte Administrator hat mir mitgeteilt, dass die Anzahl der Zombie-Prozesse, die auf dem System ausgeführt werden können, nach oben begrenzt ist. Ich glaube, 1024.

  • Ist das eine harte Faktendecke? Ich denke, Sie könnten eine beliebige Anzahl von Zombies haben, als ob Sie eine beliebige Anzahl von Prozessen haben könnten ...?
  • Unterscheidet sich der Wert von Distribution zu Distribution?
  • Was passiert, wenn wir die Obergrenze erreichen und versuchen, einen weiteren Zombie zu erschaffen?
ProfessionalAmateur
quelle
1
Laut diesem Blogartikel ist die einzige Beschränkung für Linux die Anzahl der PIDs, die Zombies nur gelegentlich betreffen.
Bahamat
2
Beide Antworten unten erwähnen ulimit -u. Ich war eine Weile verwirrt und man ulimitbekam eine C-Routine ohne Erwähnung -u. Das erwähnte ulimit ist in der Tat ein eingebautes Bash-Tool und wird in der Bash-Manpage beschrieben.
Emanuel Berg

Antworten:

11

Ich habe kein HP-UX zur Verfügung, und ich war noch nie ein großer HP-UX-Fan.

Es scheint, dass unter Linux die Anzahl der untergeordneten Prozesse pro Prozess oder möglicherweise pro Benutzer begrenzt ist. Sie können es mit dem limiteingebauten Zsh sehen (scheint analog zu ulimit -uin bash zu sein):

1002 % limit
cputime         unlimited
filesize        unlimited
datasize        unlimited
stacksize       8MB
coredumpsize    0kB
memoryuse       unlimited
maxproc         16136
  ...

Das ist auf einem Arch Linux Laptop.

Ich habe ein kleines Programm geschrieben, um dieses Limit zu testen:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

volatile int sigchld_cnt = 0;

voida
sigchld_hdlr(int signo)
{
        ++sigchld_cnt;
}

int
main(int ac, char **av)
{
        int looping = 1;
        int child_cnt = 0;
        int status;

        signal(SIGCHLD, sigchld_hdlr);

        printf("Parent PID %d\n", getpid());

        while (looping)
        {
                switch (fork())
                {
                case 0:
                        _exit(0);
                        break;
                case -1:
                        fprintf(stderr, "Problem with fork(), %d children: %s\n",
                                child_cnt, strerror(errno));
                        looping = 0;
                        break;
                default:
                        ++child_cnt;
                        break;
                }
        }

        fprintf(stderr, "Sleeping, forked %d child processes\n", child_cnt);
        fprintf(stderr, "Received %d sigchild\n", sigchld_cnt);
        sleep(10);

        looping = 1;
        do {
                int x = wait(&status);

                if (x != -1)
                        --child_cnt;
                else if (errno != EINTR) {
                        fprintf(stderr, "wait() problem %d children left: \%s\n",
                                child_cnt, strerror(errno));
                        looping = 0;
                }
        } while (looping);

        printf("%d children left, %d SIGCHLD\n", child_cnt, sigchld_cnt);

        return 0;
}

Es war überraschend schwierig, alle Zombies zu "sammeln", indem man wait(2)genügend oft anrief . Außerdem ist die Anzahl der empfangenen SIGCHLD-Signale nie die gleiche wie die Anzahl der untergeordneten Prozesse: Ich glaube, der Linux-Kernel sendet manchmal 1 SIGCHLD für eine Reihe von verlassenen untergeordneten Prozessen.

Wie auch immer, auf meinem Arch Linux-Laptop werden 16088 untergeordnete Prozesse gespalten, und das muss die Anzahl der Zombies sein, da das Programm keine wait(2)Systemaufrufe im Signalhandler ausführt.

Auf meinem Slackware 12-Server erhalte ich 6076 untergeordnete Prozesse, die dem Wert von sehr nahe kommen maxproc 6079. Meine Benutzer-ID hat 2 andere laufende Prozesse sshdund Zsh. Zusammen mit der ersten Nicht-Zombie-Instanz des obigen Programms ergibt das 6079.

Der fork(2)Systemaufruf schlägt mit dem Fehler "Ressource vorübergehend nicht verfügbar" fehl. Ich sehe keine anderen Beweise dafür, welche Ressource nicht verfügbar ist. Ich bekomme etwas andere Zahlen, wenn ich mein Programm gleichzeitig in 2 verschiedenen xterms laufen lasse, aber sie summieren sich zu der gleichen Zahl, als ob ich es in einem xterm laufen lasse. Ich gehe davon aus, dass es sich um Prozesstabelleneinträge oder einen Swap oder eine systemweite Ressource handelt und nicht nur um ein willkürliches Limit.

Ich habe momentan nichts anderes am Laufen, um es anzuprobieren.

Bruce Ediger
quelle
4

Ich weiß nicht, wo die Grenzen von HP-UX liegen. Ich kann Ihnen jedoch sagen, dass die logische Implementierung darin besteht, eine Prozesstabelle mit einer maximalen Größe zu haben. Die Gesamtzahl der Prozesstabelleneinträge ist theoretisch durch den Bereich der Prozess-IDs begrenzt, aber die meisten Implementierungen haben eine Größenbeschränkung für die Tabelle, die ein viel kleineres Maximum ergibt. Die meisten Unix-Varianten haben auch ein Benutzerlimit für die Anzahl der Prozesse. Sie können das Limit sehen, indem Sie ulimit -uin bash laufen .

Ich erwarte nicht, dass ein Unix-System eine separate Beschränkung für Zombies hat, anstatt für die Anzahl der Prozess-IDs (die sowohl tatsächliche Prozesse als auch Zombies umfassen). Wenn ein Prozess stirbt und ein Zombie wird, hat dies keinen Einfluss auf das Limit: Die Ressource (der Eintrag in der Prozesstabelle) wird zugewiesen, wenn sich ein Prozess teilt, und freigegeben, wenn der Prozess geerntet wird.

Gilles 'SO - hör auf böse zu sein'
quelle
2

Ich denke, Sie könnten eine beliebige Anzahl von Zombies haben, als ob Sie eine beliebige Anzahl von Prozessen haben könnten ...?

Ein Zombie-Prozess ist schließlich ein Prozess - in einem bestimmten Zustand -, dann sind Zombie-Prozesse wie bei regulären Prozessen auf die Verfügbarkeit und Größe der Prozesstabelle beschränkt .

Unterscheidet sich der Wert von Distribution zu Distribution?

Sicherlich genauso viele andere Parameter. Sie sollten sich nicht auf eine bestimmte Größe verlassen, oder wenn diese groß genug ist, um viele Zombie-Prozesse aufzunehmen. Wenn Sie zu viele Zombies bekommen, ist die Lösung kein großer Tisch, da er schließlich voll wird. Ein Zombie-Prozess ist an sich nicht schlecht, aber zu viele angesammelte Zombie-Prozesse sind ein Hinweis auf ein "schlecht verhaltenes" Programm, das solche Zombie-Prozesse zulässt.

Was passiert, wenn wir die Obergrenze erreichen und versuchen, einen weiteren Zombie zu erschaffen?

Sobald die Prozesstabelle voll ist - mit regulären Prozessen und Zombie-Prozessen -, kann kein neuer regulärer Prozess erstellt werden, selbst wenn das System über genügend Ressourcen verfügt - Speicher, Prozessor usw. -. Die einzige fehlende Ressource ist nur ein einzelner Eintrag in der Prozesstabelle. Bereits ausgeführte Programme - auch solche mit "gutem Benehmen" - schlagen fehl, wenn ein Unterprozess erstellt werden muss. Neue Programme konnten nicht gestartet werden, und selbst das Ausführen einzelner Befehle schlug fehl.

Laurence R. Ugalde
quelle
Even running single commands would fail.-> das ist eine große Wirkung.
Shiplu Mokaddim