Zombie trial

from Wikipedia, the free encyclopedia

A zombie process is a process table entry for a terminated process , especially in Unix-like operating systems . For reasons in process management, which are described in more detail below, under certain circumstances a process, although terminated, still appears in the process table (and thus occupies minor system resources). A zombie does no harm by itself, but it can be an indication of a mistake.

Creation of zombie processes

When a process starts a new process (using forking ) the old parent process and the new child process are named. If the child process is terminated, the parent process can ask the operating system in which way the child process was terminated: successfully, with errors, crashed, aborted, etc.

To enable this query, the entry remains in the process table after the process has ended until the parent process carries out this query - regardless of whether this information is needed or not. Until then, the child process is in the zombie state . In this state, the process itself no longer occupies any RAM except for the entry in the kernel's process table and does not consume any computing time, but it retains its PID , which cannot (yet) be reused for other processes.

The kernel sends a special signal to the parent process , namely SIGCHLD, as soon as one of its children is terminated, to inform it that it can carry out a status query so that it disappears for good. (The parent process can also query the status directly in the handler for this signal.) If the parent process does not query the status, the child remains in the process table in the zombie state.

Orphaned Processes

Another special case that is independent of zombies in and of itself, but can occur in combination with it, is when the parent process is terminated. In this case, all of its child processes are called " orphaned ". The child processes are then  “adopted” by definition by the process with PID 1 and are assigned to them as parent processes. (In the classic System V boot sequence, the so-called init process has the PID 1. In OS X, launchd takes this place. Systemd is often used here on Linux systems .) This happens for running processes as well as for zombie processes, their parents no longer exist.

Problems from zombies

Zombies are usually not a problem for an operating system, as these processes have already ended and take up very few system resources. However, the causative error in the parenting process can, under certain circumstances, such as high loads, have far greater consequences. A large number of zombies can also cause the kernel to run out of free PIDs it needs for new processes. The PID occupancy by zombies can be more problematic than their minimal memory consumption. If the number of processes on a system limits (including via maxproc in limits.conf, for example, a Forkbomb in their effect to limit), thus leading to many zombies to the fact that the kernel does not create new processes more.

Treatment of zombie processes

Although zombie processes generally do not pose a threat to the system, they can still be deleted manually - or automatically by the system.

Automated deletion

The init process has among its tasks, the completion status query of all his children as soon as they finished - so in the zombie state transferred - be. In doing so, he ensures that there are no unnecessary zombies in the system. Running processes that are adopted by the init process are not affected. Here the init process simply waits until they are finished and then queries their status.

Alternatively, you can ps axo stat,pid,comm,ppid | grep '^Z'manually send the signal SIGCHLD to the parent process of the zombie (according to the PPID information in the process table, for example from ), on the command line using , for example kill -CHLD <PID des Elternprozesses> . If the parent process does not react to this, the parent process can be terminated so that the zombie child is adopted by the init process and immediately afterwards permanently deleted by querying its status.

Special feature in the Linux kernel

The Linux kernel offers a simple - but not standardized - method of getting rid of zombies for processes that are not interested in the status of their children: If a process explicitly states that it wants to ignore SIGCHLD (as opposed to ignoring by default, if no Handler is specified), Linux automatically deletes the zombies without waiting for a status query.

Eliminate programming errors

If a process often "forgets" its children and turns them into zombies, especially if it does not react to a manual SIGCHLD, this is usually an indication of a bug in this program. For the reasons mentioned above, these errors in the program should be eliminated in order not to affect the system by the resulting zombies.

Example in C for creating zombies

Synchronous waiting for the same child process in a clearly defined order can generate zombie processes and even keep them alive for a long time. This is not necessarily a programming bug, as can be seen in the following code example:

#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>

int main(void){
    pid_t pids[10]; // Platz für 10 Prozess-IDs (die Kindprozesse)
    int i; // Laufvariable

    for (i = 0; i < 10; ++i) {
        // Der Elternprozess erzeugt nun einen Kindprozess,
        // welcher unabhängig vom Elternprozess mit der
        // erneuten Ausführung des Programms beginnt.
        // Ein Kindprozess erzeugt keinen Fork von sich selbst.
        pids[i] = fork();
        if (pids[i] == 0) {
            // dann befinden wir uns in einem der 10 Kindprozesse
            // Der erste Kindprozess wartet 10 Sekunden und jeder
            // weitere Kindprozess wartet 1 Sekunde kürzer als der
            // vorige.
            sleep(10-i);
            exit(0); // Kindprozess erfolgreich beenden
        }
    }

    // hier kommt nur der Elternprozess vorbei
    for (i = 0; i < 10; ++i){
        // Der Elternprozess wartet nun, bis der Reihe nach jeder
        // seiner 10 Kindprozesse beendet ist. Leider wird auf das
        // Kind mit der längsten Wartezeit zuerst gewartet. Obwohl
        // die anderen Kinder längst erfolgreich beendet wurden,
        // blockiert das erste Kind eine Bereinigung der Prozesstabelle
        waitpid(pids[i], NULL, 0);
    }

    return 0; // Elternprozess erfolgreich beenden
}

However, the behavior is not optimal. A better alternative would be to wait for any process, mark it as done in the array, and continue that process until the array is empty.

Individual evidence

  1. The Open Group Base Specifications Issue 7, 2018 edition IEEE Std 1003.1 ™ -2017 (Revision of IEEE Std 1003.1-2008): Consequences of Process Termination

See also