僵尸进程
1.什么是僵尸进程
一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他,那么他将变成一个僵尸进程。当用ps命令观察进程的执行状态时,看到这些进程的状态栏为defunct。如果该进程的父进程先结束,那么该进程就不会变成僵尸进程。因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程,看看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init进程来接管他,成为他的父进程,从而保证每个进程都会有一个父进程。而Init进程会自动wait其子进程,因此被Init接管的所有进程都不会变成僵尸进程。
僵尸进程实例:
代码如下:
1 #include<stdio.h>
2 #include<assert.h>
3 #include<string.h>
4 #include<unistd.h>
5 #include<stdlib.h>
6
7 int main()
8 {
9 char* s = NULL;
10 int n = 0;
11
12 pid_t pid = fork();
13 assert(pid != -1);
14
15 if(pid == 0)
16 {
17 s = "child";
18 n = 3;
19 }
20 else
21 {
22 s = "parent";
23 n = 7;
24 }
25
26 for(int i = 0;i < n;i++ )
27 {
28 printf("pid = %d,s = %s\n",getpid(),s);
29 sleep(1);
30
31 }
32 exit(3);//退出程序,并返回值3
33 }
34
编译代码,使可执行程序在后台运行,在运行过程中用ps命令查看进程
wys@DESKTOP-2OU3HRV:~/mycode/day09$ gcc -o main main.c
wys@DESKTOP-2OU3HRV:~/mycode/day09$ ls
main main.c
wys@DESKTOP-2OU3HRV:~/mycode/day09$ ./main&
[1] 242
wys@DESKTOP-2OU3HRV:~/mycode/day09$ pid = 242,s = parent
pid = 243,s = child
pspid = 242,s = parent
pid = 243,s = child
PID TTY TIME CMD
11 tty1 00:00:00 bash
242 tty1 00:00:00 main
243 tty1 00:00:00 main
244 tty1 00:00:00 ps
wys@DESKTOP-2OU3HRV:~/mycode/day09$ pid = 242,s = parent
pid = 243,s = child
ps
PID TTY TIME CMD
11 tty1 00:00:00 bash
242 tty1 00:00:00 main
243 tty1 00:00:00 main
245 tty1 00:00:00 ps
wys@DESKTOP-2OU3HRV:~/mycode/day09$ pid = 242,s = parent
pspid = 242,s = parent
PID TTY TIME CMD
11 tty1 00:00:00 bash
242 tty1 00:00:00 main
243 tty1 00:00:00 main <defunct>
246 tty1 00:00:00 ps
wys@DESKTOP-2OU3HRV:~/mycode/day09$ pid = 242,s = parent
pid = 242,s = parent
父进程先于子进程结束,子进程进入僵尸状态!
243 tty1 00:00:00 main <defunct>
2.父进程通过调用wait()完成处理僵尸进程
查看**wait()**命令使用方法
pid_t wait(int *status);
WIFEXITED(status) 这个宏用来指出子进程是否为正常退出的,如果是,它会返回一个非零值。(请注意,虽然名字一样,这里的参数status并不同于wait唯一的参数–指向整数的指针status,而是那个指针所指向的整数,切记不要搞混了。)
WEXITSTATUS(status) 当WIFEXITED返回非零值时,可以用这个宏来提取子进程的返回值,如果子进程调用exit(5)退出,WEXITSTATUS(status)就会返回5;
父进程调用wait(),代码如下:
1 #include<stdio.h>
2 #include<assert.h>
3 #include<string.h>
4 #include<unistd.h>
5 #include<stdlib.h>
6 #include<sys/wait.h>
7
8 int main()
9 {
10 char* s = NULL;
11 int n = 0;
12
13 pid_t pid = fork();
14 assert(pid != -1);
15
16 if(pid == 0)
17 {
18 s = "child";
19 n = 3;
20 }
21 else
22 {
23 s = "parent";
24 n = 7;
25 int val = 0;
26 wait(&val);
27 if(WIFEXITED(val))
28 {
29 printf("val = %d\n",WEXITSTATUS(val));//如果子进程未结束,那么wait会阻塞
30 }
31 }
32
33 for(int i = 0;i < n;i++ )
34 {
35 printf("pid = %d,s = %s\n",getpid(),s);
36 sleep(1);
37
38 }
39 exit(3);//退出程序,并返回值3
40 }
编译运行:
wys@DESKTOP-2OU3HRV:~/mycode/day09$ gcc -o main main.c
wys@DESKTOP-2OU3HRV:~/mycode/day09$ ls
main main.c
wys@DESKTOP-2OU3HRV:~/mycode/day09$ ./main
pid = 129,s = child
pid = 129,s = child
pid = 129,s = child
val = 3
pid = 128,s = parent
pid = 128,s = parent
pid = 128,s = parent
pid = 128,s = parent
pid = 128,s = parent
pid = 128,s = parent
pid = 128,s = parent
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/95581.html