tavoite: analysoi, miten zombi-prosessit tai lakkautetut prosessit luodaan ja miten ne poistetaan prosessitaulukosta.
zombiprosessi tai lakkautettu prosessi on prosessi, joka on suorittanut suorituksen loppuun, mutta jolla on silti merkintä prosessitaulukossa. Tämä tapahtuu lapsiprosesseille, jotka on haarukoitu emoprosessilla fork()
– järjestelmäkutsun avulla, mutta joita emoprosessi ei ole korjannut wait()
– järjestelmäkutsun avulla.
vanhemman prosessin on soitettava wait()
(tai waitpid()
) järjestelmäkutsu saadakseen lapsiprosessin poistumistilan, kun lapsiprosessi on päättynyt. Jos wait()
– puhelua ei suoriteta vanhemman prosessilla, lapsen prosessista tulee zombiprosessi.
SIGCHLD
signaali lähetetään vanhemman prosessiin aina, kun lapsen prosessi päättyy. Emoprosessissa on oltava SIGCHLD
signaalinkäsittelijäfunktio, joka on määritelty kutsulla wait()
– tämä poistaa lapsiprosessin prosessitaulukosta.
zombiprosessien poistamiseksi järjestelmästä SIGCHLD
– signaali voidaan lähettää vanhemmalle manuaalisesti kill
– komennolla. Jos vanhempainprosessi kieltäytyy edelleen korjaamasta zombiprosessia, ja jos vanhempainprosessi voidaan tappaa, seuraava askel on tappaa vanhempainprosessi. Kun lapsen prosessi menettää vanhemman prosessinsa, init
(PID 1) tulee sen uudeksi vanhemmaksi. init
suorittaa määräajoin wait()
– järjestelmäkutsun korjatakseen minkä tahansa zombiprosessin, jossa init
on vanhempi.
kirjoitin yksinkertaisen C-ohjelman zombiprosessin luomiseksi.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
#sisältää <stdion.h>
#sisältää < stdlibin.h>
#sisältää <sys / tyypit.h>
#sisältää <SYS / odota.h>
#include <unistd.h>
#sisältää <errno.h>
int main ()
{
pid_t child_pid;
int child_status;
child_pid = fork ();
if (child_pid > 0) {
// parent process nukkuu 30 sekuntia ja poistuu ilman odotuskutsua ()
fprintf (stderr, ”parent process – %d\n”, getpid());
Uni(30);
poistu(0);
}
else if (child_pid == 0) {
// lapsiprosessi poistuu välittömästi
fprintf (stderr, ”lapsiprosessi – %d\n”, getpid());
poistu(0);
}
else if (child_pid == -1) {
// haarukka () virhe
perror (”haarukka () puhelu epäonnistui”);
exit (-1;
}
else {
/ / näin ei saa tapahtua
fprintf (stderr, ”% D: n tuntematon paluuarvo haarukasta () puhelusta”, child_pid);
exit (-2);
}
paluu 0;
}
|
Tallenna yllä oleva koodi nimellä zombie.c
ja käännä se käyttäen koodia gcc
.
$ gcc zombie.c -o zombie
seuraavaksi, suorita ohjelma.
$ ./zombie parent process - 26570child process - 26571
toisesta päätteestä, tee ps
näyttääksesi käynnissä olevat prosessit. Näet zombie prosessi.
$ ps -ef | grep zombieibrahim 26570 22886 0 15:59 pts/2 00:00:00 ./zombieibrahim 26571 26570 0 15:59 pts/2 00:00:00 <defunct>
kun emoprosessi on päättynyt (30 sekunnin kuluttua), zombiprosessi poistetaan prosessitaulukosta init
– prosessilla.
Mohamed Ibrahim
ibrahim = { interest_in(unix, linux, android, open_source, reverse_engineering); coding(C, shell, php, python, java, javascript, nodejs, react); plays_on(xbox, ps4); linux_desktop_user (true); }