什么是孤儿进程和僵尸进程?
一、孤儿进程
1. 什么是孤儿进程:
如果一个子进程的父进程先于子进程结束,则该子进程将变成孤儿进程。它将由init进程收养,成为init进程的子进程。
通俗来说,就是父亲(父进程)去世了,儿子(子进程)成了孤儿(孤儿进程),然后儿子被孤儿院(init进程)收养。
2. 怎么产生孤儿进程:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(void) { int pid; if((pid = fork()) == -1) { perror("fork"); exit(1); } if(pid == 0) { //子进程进入之后未一直死循环,不退出 while(1) { sleep(1); } } else {//可以不必写else,为了看的清楚写明白点。 //父进程进入else后直接退出了,而子进程未退出,则子进程成为孤儿进程 ; } return 0; }
截图:
二、僵尸进程
1.什么是僵尸进程?
(1). 僵尸进程是一种特殊的Linux进程状态
(2). 它已经放弃了几乎所有的内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其父进程收集,除此之外,僵尸进程不再占有任何内存空间。
(3).它需要它的父进程来为它收尸,例如wait()和waitpid(),如果在父进程存在期间未结束时,一直未给该已经结束的子进程收尸,那么它就会一直保持僵尸状态。
2.僵尸进程的影响:
已经结束的进程,但是没有从进程表中删除,太多了会导致进程表里面的条目满了,进而导致系统崩溃,但不占用其他系统资源
3.产生一个僵尸进程:
zombie.c文件
>
#include
截图:
3.怎么防止僵尸进程的产生?
>
- 僵尸进程产生的原因是父进程没有给子进程收尸,那么解决方法就是让父进程知道子进程挂了,然后去给子进程收尸。 那父进程怎么知道子进程挂了呢?
- 当子进程结束后,系统会向其父进程发送一个信号SIGCHLD,来通知父进程。那么我们可以通过拦截这个信号并在处理该信号的函数中为子进程收尸就可以了!
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
//处理子进程退出信号
void sigcb(int signo)
{
int status;
if( signo == SIGCHLD )
{
printf("child exit!\n");
//接收子进程退出信息(为子进程收尸)
wait(&status);
}
}
int main(void)
{
int pid = -1;
//绑定SIGCHLD信号和该信号的处理函数sigcb
signal(SIGCHLD, sigcb);
pid = fork();
if(pid < 0)
{
return -1;
}
else if(pid == 0)
{
//子进程退出
exit(0);
}
while(1)
{ //父进程死循环,不退出
sleep(1);
}
return 0;
}
截图: