孤儿进程和僵尸进程
文章目录
- 孤儿进程
- 僵尸进程
孤儿进程
定义
- 父进程运行结束,但子进程还在运行(未运行结束),这样的子进程就称为孤儿进程(Orphan Process)
- 每当出现一个孤儿进程的时候,内核就把孤儿进程的父进程设置为 init ,而 init 进程会循环地 wait() 它的已经退出的子进程。
- 孤儿进程并不会有什么危害
program
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
// 创建子进程
pid_t pid = fork();
// 判断是父进程还是子进程
if(pid > 0) {
printf("i am parent process, pid : %d, ppid : %d\n", getpid(), getppid());
} else if(pid == 0) {
sleep(1);
// 当前是子进程
printf("i am child process, pid : %d, ppid : %d\n", getpid(),getppid());
}
// for循环
for(int i = 0; i < 3; i++) {
printf("i : %d , pid : %d\n", i , getpid());
}
return 0;
}
运行结果
(base) user@ubuntu:~/Desktop/OS/NiuKe$ gcc -o test test.c -std=c99
(base) user@ubuntu:~/Desktop/OS/NiuKe$ ./test
i am parent process, pid : 4483, ppid : 3615
i : 0 , pid : 4483
i : 1 , pid : 4483
i : 2 , pid : 4483
(base) user@ubuntu:~/Desktop/OS/NiuKe$ i am child process, pid : 4484, ppid : 1
i : 0 , pid : 4484
i : 1 , pid : 4484
i : 2 , pid : 4484
僵尸进程
定义
子进程先于父进程退出后,子进程的PCB需要其父进程释放,但是父进程并没有释放子进程的PCB,这样的子进程就称为僵尸进程。僵尸进程实际上是一个已经死掉的进程。
正常进程的退出流程:当一个进程完成时,Linux 内核通过发送SIGCHLD
信号通知它的父进程。然后父进程执行wait()
系统调用来读取子进程的状态并获取退出代码。清理结束此进程。
僵尸进程:父进程无法通过调用wait
或waitpid
得到它的退出状态清除掉这个进程,导致已完成进程的僵尸状态留在进程表中,因此它作为僵尸进程出现在进程列表中。影响可用的进程号从而导致系统不能产生新的进程。
创建
program
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
int main(int argc, const char *argv[])
{
pid_t pid=fork();//创建子进程
if(pid>0)
{
printf("this a little father%d\n",getpid());
}
else if(pid==0)
{
int i=0;
while(i<3){
printf("this a little father%d,child:%d\n",getppid(),getpid());
i++;
}
_exit(0);//exit和_exit的区别(刷新缓冲区)
}
else
perror("fork");
return 0;
}
简单编译一波
(base) user@ubuntu:~/Desktop/HTTP/studyFork$ gcc a.c -o a
(base) user@ubuntu:~/Desktop/HTTP/studyFork$ ./a
this a little father3191
this a little father3191,child:3192
this a little father2042,child:3192
this a little father2042,child:3192
linux下查看 ps aux | egrep "Z|defunct"
(base) user@ubuntu:~/Desktop/HTTP/studyFork$ ps aux | egrep "Z|defunct"
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
user 3194 0.0 0.0 16180 1116 pts/0 S+ 08:18 0:00 grep -E --color=auto Z|defunct
处理僵尸进程
1.唤起父进程,由父进程清理僵尸进程。
根据子进程ID查找父进程的ID
ps -o ppid= <Child PID>
然后根据查找的父进程删除
kill -s SIGCHLD <Parernt PID>
2.直接杀死父进程
注:杀死父进程会影响其所有子进程
kill -9 <Parernt PID>