Czy istnieje górny limit liczby procesów zombie, które możesz mieć?


17

Kiedyś pracowałem z systemem HP-UX, a stary administrator powiedział mi, że istnieje górny limit liczby procesów zombie, które możesz mieć w systemie, uważam, że 1024.

  • Czy to jest twardy pułap? Myślę, że możesz mieć dowolną liczbę zombie, tak jakbyś mógł mieć dowolną liczbę procesów ...?
  • Czy różni się wartość od dystrybucji do dystrybucji?
  • Co się stanie, jeśli przekroczymy górny limit i spróbujemy stworzyć kolejnego zombie?

1
Zgodnie z tym artykułem na blogu jedynym ograniczeniem w Linuksie jest liczba PID, które tylko przypadkowo wpływają na zombie.
bahamat

2
Obie odpowiedzi poniżej wspominają ulimit -u. Przez chwilę byłem zdezorientowany, ponieważ man ulimitdostałem rutynę C bez wzmianki -u. Wspomniany ulimit jest w rzeczywistości wbudowanym narzędziem bashowym i jest opisany na stronie podręcznika bash.
Emanuel Berg

Odpowiedzi:


11

Nie mam dostępnego HP-UX i nigdy nie byłem wielkim fanem HP-UX.

Wygląda na to, że w Linuksie istnieje ograniczenie liczby procesów potomnych na proces lub użytkownika. Możesz to zobaczyć dzięki limitwbudowanemu Zsh (wydaje się analogiczny jak ulimit -uw bash):

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

To na laptopie Arch Linux.

Napisałem mały program do przetestowania tego limitu:

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

Zaskakująco trudno było „zebrać” wszystkie zombie, dzwoniąc wait(2)wystarczająco dużo razy. Ponadto liczba odebranych sygnałów SIGCHLD nigdy nie jest taka sama jak liczba rozwidlonych procesów potomnych: Wierzę, że jądro Linuksa czasami wysyła 1 SIGCHLD dla szeregu zakończonych procesów potomnych.

W każdym razie na moim laptopie Arch Linux, rozwidlam procesy potomne 16088, a to musi być liczba zombie, ponieważ program nie wykonuje wait(2)wywołań systemowych w module obsługi sygnału.

Na moim serwerze Slackware 12 otrzymuję 6076 procesów potomnych, co ściśle odpowiada wartości maxproc 6079. Mój identyfikator użytkownika ma uruchomione 2 inne procesy sshdi Zsh. Wraz z pierwszą instancją programu innego niż zombie powyżej, która tworzy 6079.

fork(2)Wywołanie awarii systemu z „Zasoby chwilowo niedostępny” błędu. Nie widzę żadnych innych dowodów wskazujących, który zasób jest niedostępny. Otrzymuję nieco inne liczby, jeśli uruchamiam mój program jednocześnie w 2 różnych xtermach, ale sumują się one do tej samej liczby, jak gdybym uruchamiał go w jednym xtermie. Zakładam, że są to wpisy w tabeli procesów, swap lub jakiś systemowy zasób, a nie tylko arbitralny limit.

Nie mam już nic innego do przetestowania.


4

Nie wiem, jakie są ograniczenia HP-UX. Mogę jednak powiedzieć, że logiczną implementacją jest posiadanie tabeli procesów o maksymalnym rozmiarze. Całkowita liczba wpisów w tabeli procesów jest teoretycznie ograniczona przez zakres identyfikatorów procesów, ale większość implementacji ma limit wielkości tabeli, który daje znacznie mniejsze maksimum. Większość wariantów uniksowych ma również limit liczby procesów na użytkownika; możesz zobaczyć limit, uruchamiając ulimit -uw bash.

Nie spodziewam się, że system uniksowy będzie miał oddzielny limit na zombie, a nie na liczbę identyfikatorów procesów (które obejmują zarówno rzeczywiste procesy, jak i zombie). Kiedy więc proces umiera i staje się zombie, nie ma to wpływu na limit: zasób (pozycja w tabeli procesów) jest przydzielany, gdy proces rozwidla się i uwalniany, gdy proces jest zbierany.


2

Myślę, że możesz mieć dowolną liczbę zombie, tak jakbyś mógł mieć dowolną liczbę procesów ...?

Proces zombie jest wreszcie procesem - w specjalnym stanie - wówczas procesy zombie są ograniczone do dostępności i wielkości tabeli procesów, tak jak w przypadku zwykłych procesów.

Czy różni się wartość od dystrybucji do dystrybucji?

Z pewnością tak wiele innych parametrów. Nie powinieneś polegać na określonym rozmiarze lub jeśli jest on wystarczająco duży, aby pomieścić wiele procesów zombie. Jeśli dostajesz zbyt wiele zombie, rozwiązanie nie jest dużym stołem, ponieważ w końcu się zapełni. Proces zombie sam w sobie nie jest zły, ale zbyt wiele nagromadzonych procesów zombie jest oznaką „źle zachowującego się” programu, który pozwala takim procesom zombie.

Co się stanie, jeśli przekroczymy górny limit i spróbujemy stworzyć kolejnego zombie?

Gdy tabela procesów zostanie zapełniona - procesów zwykłych i procesów zombie - nie można utworzyć nowego procesu - nawet jeśli system ma wystarczającą ilość zasobów - pamięć, procesor itp. -. Brakuje tylko jednego zasobu w tabeli procesów. Już uruchomione programy - nawet te „dobrze wychowane” - zaczną się nie powieść, gdy będą musiały utworzyć podproces. Nie można uruchomić nowych programów, a nawet uruchomienie pojedynczych poleceń nie powiedzie się.


Even running single commands would fail.-> to duży wpływ.
Shiplu Mokaddim
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.