概念:
子进程退出,父进程不退出,并且父进程不回收子进程的资源;这时候子进 程就是僵尸进程
注意:
-
僵尸进程只能被回收,不能被kill;
-
父进程退出后,子进程的资源将由内核回收;
危害:
-
占用进程号
-
占用内存空间,占用物理空间,以及进程控制块.....
代码:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
//创建子进程
pid_t pid = fork();
if (pid > 0)
{
//父进程
printf("This is parent\n");
while (1)
{
printf("parent -------\n");
sleep(1);
}
}
else if(0 == pid)
{
//子进程
printf("This is child\n");
//退出子进程 并不做回收处理
_exit(0);
}
else
{
perror("fork");
return -1;
}
return 0;
}
测试:
root@VM-12-9-ubuntu:8-01# a
This is parent
child -------
This is child
child -------
child -------
child -------
^C // Ctrl+C可以退出
root@VM-12-9-ubuntu:8-01#
//未 Ctrl+C 时查看进程 发现有Z+僵尸进程
root@VM-12-9-ubuntu:8-01# ps -ajx
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
15970 18888 18888 15970 pts/2 18888 S+ 0 0:00 ./a.out
18888 18889 18888 15970 pts/2 18888 Z+ 0 0:00 [a.out] <defunct>
//kill -9命令执行后僵尸进程仍在运行
root@VM-12-9-ubuntu:8-01# kill -9 18889
//Ctrl+C结束父进程后僵尸进程被系统回收 僵尸进程消失
如何回收僵尸进程:
-
wait/waitpid函数回收,缺点:函数阻塞,父进程不能做自己的事情。
-
用信号的方式回收。
修改代码:
//在父进程中加入wait函数,因为等待回收子进程所以一直在阻塞状态
//直到子进程被退出,wait函数执行完毕
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, const char *argv[])
{
//创建子进程
pid_t pid = fork();
if (pid > 0)
{
//父进程
printf("This is parent\n");
//回收_exit返回值为0的子进程
wait(0);
printf("wait函数运行完毕\n");
while (1)
{
printf("parent ------\n");
sleep(1);
}
}
else if(0 == pid)
{
//子进程
printf("This is child\n");
//退出子进程
_exit(0);
}
else
{
perror("fork");
return -1;
}
return 0;
}
测试:
root@VM-12-9-ubuntu:8-01# a
This is parent
This is child
wait函数运行完毕
parent ------
parent ------
parent ------
parent ------
parent ------
^C //Ctrl+C可以退出
root@VM-12-9-ubuntu:8-01#
//未退出父进程时查看运行中的进程 未发现僵尸进程
root@VM-12-9-ubuntu:8-01# ps -ajx
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
15970 23342 23342 15970 pts/2 23342 S+ 0 0:00 ./a.out