Sobes.tech
Middle

Który sygnał: SIGTERM czy SIGKILL może wywołać procesy zombie?

sobes.tech AI

Odpowiedź od AI

SIGTERM nie może bezpośrednio tworzyć procesów zombie. Wysyła powiadomienie do procesu o konieczności poprawnego zakończenia, dając mu szansę na zwolnienie zasobów. Jeśli proces zignoruje SIGTERM, nie zakończy się.

SIGKILL nie może tworzyć procesów zombie. Natychmiast kończy proces, nie dając mu możliwości poprawnego zakończenia ani utworzenia procesów potomnych.

Proces zombie pojawia się, gdy proces potomny kończy działanie, ale jego proces macierzysty nie wywołuje funkcji wait() lub waitpid(), aby zebrać jego status zakończenia. Proces macierzysty jest odpowiedzialny za zebranie statusu zakończonych procesów potomnych. Bez względu na to, jak zakończył się proces potomny (przez SIGTERM, SIGKILL lub inny powód), staje się zombie, dopóki proces macierzysty go "zebra" lub sam nie zakończy działania.

Zatem zombie są tworzone przez proces macierzysty, który nie obsługuje zakończenia swoich procesów potomnych, niezależnie od sygnału, który doprowadził do zakończenia procesu potomnego.

Przykład w C demonstrujący tworzenie zombie:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
    pid_t pid = fork(); // Tworzymy proces potomny

    if (pid == 0) {
        // Kod procesu potomnego
        printf("Proces potomny (PID: %d) kończy się.\n", getpid());
        exit(0); // Proces potomny kończy się
    } else if (pid > 0) {
        // Kod procesu macierzystego
        printf("Proces macierzysty (PID: %d) utworzył potomka (PID: %d).\n", getpid(), pid);
        // Proces macierzysty nie wywołuje wait() lub waitpid(), tworząc zombie

        printf("Proces macierzysty śpi. Potomek powinien stać się zombie.\n");
        sleep(60); // Proces macierzysty śpi, aby potomek mógł się zakończyć i stać się zombie
    } else {
        // Błąd przy fork
        perror("Błąd przy fork");
        return 1;
    }

    return 0;
}

W tym przykładzie, proces potomny kończy się, ale proces macierzysty nie wywołuje wait(), co prowadzi do pojawienia się zombie. Zakończenie potomka w tym przypadku nie było bezpośrednio spowodowane SIGTERM lub SIGKILL, ale zasada jest taka sama: proces macierzysty nie zebrał statusu.

Gdyby potomny proces został zabity przez SIGKILL, również stałby się zombie, jeśli proces macierzysty nie zebrał jego statusu. SIGKILL po prostu wymusza zakończenie procesu, a jego status końcowy pozostaje w tabeli procesów, dopóki proces macierzysty go nie zbierze.