cíl: analyzovat, jak jsou vytvořeny zombie procesy nebo zaniklé procesy a jak je odstranit z procesní tabulky.
zombie proces nebo zaniklý proces je proces, který dokončil spuštění, ale stále má položku v tabulce procesů. K tomu dochází u podřízených procesů, které byly rozvětveny nadřazeným procesem pomocí systémového volání fork()
, ale nebyly využity nadřazeným procesem pomocí systémového volání wait()
.
nadřazený proces musí provést systémové volání wait()
(nebo waitpid()
), aby získal Stav ukončení podřízeného procesu po ukončení podřízeného procesu. Pokud volání wait()
není provedeno nadřazeným procesem, podřízený proces se stane zombie procesem.
signál SIGCHLD
je odeslán do nadřazeného procesu vždy, když je podřízený proces ukončen. Nadřazený proces musí mít funkci SIGCHLD
signal handler definovanou voláním na wait()
– tím se odebere podřízený proces z procesní tabulky.
Chcete-li odstranit zombie procesy ze systému, může být signál SIGCHLD
odeslán rodiči ručně pomocí příkazu kill
. Pokud nadřazený proces stále odmítá sklízet zombie proces a pokud může být nadřazený proces zabit, dalším krokem je zabití nadřazeného procesu. Když podřízený proces ztratí svůj nadřazený proces, init
(PID 1) se stává jeho novým rodičem. init
pravidelně provádí systémové volání wait()
, aby sklízel všechny zombie procesy s init
jako rodičem.
napsal jsem jednoduchý program C pro vytvoření zombie procesu.
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
|
#zahrnout <stdio.h>
#zahrnout <stdlib.h>
#zahrnout <sys/typy.h>
#zahrnout < sys/wait.h>
#zahrnout <unistd.h>
#zahrnout <errno.h>
int main ()
{
pid_t child_pid;
int child_status;
child_pid = fork ();
if (child_pid > 0) {
// nadřazený proces bude spát po dobu 30 sekund a ukončit, bez volání čekat ()
fprintf (stderr, „nadřazený proces – %d\n“, getpid());
spánek(30);
exit(0);
}
else if (child_pid == 0) {
// podřízený proces okamžitě ukončí
fprintf (stderr,“ podřízený proces – %d\n“, getpid());
exit(0);
}
else if (child_pid == -1) {
// fork () error
perror („fork() call failed“);
exit (-1) ;
}
else {
// to by se nemělo stát
fprintf(stderr, „neznámá návratová hodnota %D z volání fork ()“, child_pid);
exit (-2);
}
návrat 0;
}
|
Uložte výše uvedený kód jako zombie.c
a zkompilujte jej pomocí gcc
.
$ gcc zombie.c -o zombie
dále spusťte program.
$ ./zombie parent process - 26570child process - 26571
z jiného terminálu proveďte ps
pro zobrazení běžících procesů. Uvidíte zombie proces.
$ 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>
po ukončení nadřazeného procesu (po 30 sekundách) bude proces zombie odstraněn z procesní tabulky procesem init
.
Mohamed Ibrahim
ibrahim = { interested_in(unix, linux, android, open_source, reverse_engineering); kódování(c, shell, php, python, java, javascript, nodejs, react); plays_on(xbox, ps4); linux_desktop_user(true); }