Sobes.tech
Middle

Ποιο σήμα: SIGTERM ή SIGKILL μπορεί να δημιουργήσει ζόμπι διαδικασίες;

sobes.tech AI

Απάντηση από AI

Το SIGTERM δεν μπορεί να δημιουργήσει άμεσα διεργασίες ζόμπι. Αποστέλλει μια ειδοποίηση στη διαδικασία να τερματίσει σωστά, δίνοντάς της την ευκαιρία να απελευθερώσει πόρους. Αν η διαδικασία αγνοεί το SIGTERM, δεν θα τερματίσει.

Το SIGKILL δεν μπορεί να δημιουργήσει διεργασίες ζόμπι. Τερματίζει αμέσως τη διαδικασία, χωρίς να της δώσει την ευκαιρία να τερματίσει σωστά ή να δημιουργήσει παιδικές διεργασίες.

Μια διεργασία ζόμπι εμφανίζεται όταν μια παιδική διεργασία τερματίζει, αλλά η γονική της διεργασία δεν καλεί τη λειτουργία wait() ή waitpid() για να συλλέξει την κατάσταση τερματισμού της. Η γονική διεργασία είναι υπεύθυνη για τη συλλογή της κατάστασης των τερματισμένων παιδικών διεργασιών. Ανεξάρτητα από το πώς τερματίστηκε η παιδική διεργασία (με SIGTERM, SIGKILL ή για άλλο λόγο), γίνεται ζόμπι μέχρι η γονική να το "συλλέξει" ή να τερματίσει και η ίδια.

Επομένως, τα ζόμπι δημιουργούνται από τη γονική διεργασία, που δεν χειρίζεται το τερματισμό των παιδικών διεργασιών της, ανεξάρτητα από το σήμα που οδήγησε στον τερματισμό.

Παράδειγμα σε C που δείχνει τη δημιουργία ζόμπι:

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

int main() {
    pid_t pid = fork(); // Δημιουργία παιδικής διεργασίας

    if (pid == 0) {
        // Κώδικας παιδικής διεργασίας
        printf("Παιδική διεργασία (PID: %d) τερματίζει.\n", getpid());
        exit(0); // Η παιδική διεργασία τερματίζει
    } else if (pid > 0) {
        // Κώδικας γονικής διεργασίας
        printf("Γονική διεργασία (PID: %d) δημιούργησε παιδί (PID: %d).\n", getpid(), pid);
        // Η γονική δεν καλεί `wait()` ή `waitpid()`, δημιουργώντας ζόμπι

        printf("Η γονική διεργασία κοιμάται. Το παιδί θα πρέπει να γίνει ζόμπι.\n");
        sleep(60); // Η γονική κοιμάται, ώστε το παιδί να τερματίσει και να γίνει ζόμπι
    } else {
        // Σφάλμα στο fork
        perror("Σφάλμα στο fork");
        return 1;
    }

    return 0;
}

Σε αυτό το παράδειγμα, το παιδικό διαδικασία τερματίζει, αλλά η γονική δεν καλεί wait(), με αποτέλεσμα να δημιουργούνται ζόμπι. Ο τερματισμός του παιδιού σε αυτήν την περίπτωση δεν προκλήθηκε άμεσα από SIGTERM ή SIGKILL, αλλά η αρχή είναι ίδια: η γονική δεν έχει συλλέξει την κατάσταση.

Αν το παιδί δολοφονηθεί με SIGKILL, θα γίνει επίσης ζόμπι αν η γονική δεν έχει συλλέξει την κατάσταση του. Το SIGKILL τερματίζει βίαια τη διαδικασία, αλλά η κατάσταση τερματισμού παραμένει στον πίνακα διεργασιών μέχρι να την συλλέξει η γονική.