Y a-t-il une limite supérieure au nombre de processus zombies que vous pouvez avoir?

17

J'avais l'habitude de travailler avec un système HP-UX et l'ancien administrateur m'a dit qu'il y avait une limite supérieure sur le nombre de processus zombies que vous pouvez avoir sur le système, je crois 1024.

  • Est-ce un plafond factuel? Je pense que vous pourriez avoir n'importe quel nombre de zombies comme si vous pouviez avoir un certain nombre de processus ...?
  • Est-ce une valeur différente d'une distribution à l'autre?
  • Que se passe-t-il si nous atteignons la limite supérieure et essayons de créer un autre zombie?
ProfessionnelAmateur
la source
1
Selon cet article de blog, la seule limite sur Linux est le nombre de PID, qui n'affecte qu'incidemment les zombies.
bahamat
2
Les deux réponses ci-dessous mentionnent ulimit -u. J'ai été confus pendant un certain temps car man ulimitj'ai eu une routine C sans aucune mention -u. L'ulimit mentionné est en fait un outil bash intégré et il est décrit dans la page de manuel bash.
Emanuel Berg

Réponses:

11

Je n'ai pas HP-UX à ma disposition et je n'ai jamais été un grand fan de HP-UX.

Il semble que sous Linux, une limite par processus ou peut-être par utilisateur sur le nombre de processus enfants existe. Vous pouvez le voir avec le limitZsh intégré (semble être similaire à ulimit -ubash):

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

C'est sur un ordinateur portable Arch Linux.

J'ai écrit un petit programme pour tester cette limite:

#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;
}

Il était étonnamment difficile de "collecter" tous les zombies en appelant wait(2)suffisamment de fois. De plus, le nombre de signaux SIGCHLD reçus n'est jamais le même que le nombre de processus enfants bifurqués: je crois que le noyau Linux envoie parfois 1 SIGCHLD pour un certain nombre de processus enfants sortis.

Quoi qu'il en soit, sur mon ordinateur portable Arch linux, je reçois 16088 processus enfants fourchus, et cela doit être le nombre de zombies, car le programme ne fait pas d' wait(2)appels système dans le gestionnaire de signaux.

Sur mon serveur Slackware 12, j'obtiens 6076 processus enfants, ce qui correspond étroitement à la valeur de maxproc 6079. Mon ID utilisateur a 2 autres processus en cours d'exécution sshdet Zsh. Avec la première instance non zombie du programme ci-dessus qui fait 6079.

L' fork(2)appel système échoue avec une erreur «Ressource temporairement indisponible». Je ne vois aucune autre preuve de quelle ressource n'est pas disponible. J'obtiens des nombres quelque peu différents si j'exécute mon programme simultanément dans 2 xterms différents, mais ils s'additionnent au même nombre que si je l'exécute dans un xterm. Je suppose que ce sont des entrées de table de processus, ou un échange ou une ressource à l'échelle du système, et pas seulement une limite arbitraire.

Je n'ai rien d'autre à faire pour l'essayer en ce moment.

Bruce Ediger
la source
4

Je ne sais pas quelles sont les limites de HP-UX. Je peux cependant vous dire que l'implémentation logique est d'avoir une table de processus avec une taille maximale. Le nombre total d'entrées de table de processus est théoriquement limité par la plage d'ID de processus, mais la plupart des implémentations ont une limite de taille pour la table qui donne un maximum beaucoup plus petit. La plupart des variantes Unix ont également une limite par utilisateur sur le nombre de processus; vous pouvez voir la limite en exécutant ulimit -uen bash.

Je ne m'attends pas à ce qu'un système Unix ait une limite distincte sur les zombies, plutôt que sur le nombre d'ID de processus (qui inclut les processus réels ainsi que les zombies). Ainsi, lorsqu'un processus meurt et devient un zombie, cela n'affecte pas la limite: la ressource (l'entrée dans la table de processus) est allouée lorsqu'un processus bifurque et libérée lorsque le processus est récolté.

Gilles 'SO- arrête d'être méchant'
la source
2

Je pense que vous pourriez avoir n'importe quel nombre de zombies comme si vous pouviez avoir un certain nombre de processus ...?

Un processus zombie est finalement un processus - dans un état spécial - puis les processus zombies sont limités à la disponibilité et à la taille de la table de processus, comme pour les processus réguliers .

Est-ce une valeur différente d'une distribution à l'autre?

Sûrement, comme beaucoup d'autres paramètres. Vous ne devez pas relayer sur une taille spécifique, ou si elle est assez grande pour contenir de nombreux processus de zombies. Si vous obtenez trop de zombies, la solution n'est pas une grande table, car elle sera finalement pleine. Un processus zombie n'est pas mauvais en soi, mais le fait d'avoir trop de processus zombies accumulés est une indication d'un programme "mal comporté" qui autorise de tels processus zombies.

Que se passe-t-il si nous atteignons la limite supérieure et essayons de créer un autre zombie?

Une fois que la table de processus est pleine - de processus réguliers et zombies -, aucun nouveau processus - régulier - ne peut être créé, même si le système a suffisamment de ressources - mémoire, processeur, etc. -. La seule ressource manquante est une seule entrée dans la table de processus. Les programmes déjà en cours d'exécution - même ceux "bien comportés" - commenceront à échouer lorsqu'ils auront besoin de créer un sous-processus. De nouveaux programmes n'ont pas pu être démarrés et même l'exécution de commandes uniques échouait.

Laurence R. Ugalde
la source
Even running single commands would fail.-> c'est un gros impact.
Shiplu Mokaddim