Linux 僵尸进程

僵尸进程

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WYSCODER

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值