僵尸进程和孤儿进程的模拟和处理

进程的创建

创建一个进程的一般工作:
1.分配一个进程PID(0 - /proc/sys/kernel/pid_max)
0号进程是内核进程 ,它创建1号进程。
0号还将进程从物理内存搬到磁盘,和从磁盘搬运到物理内存
进程是树状结构
2.分配(PCB)结构体,通过页目录,页表,物理内存三级拷贝父进程中的绝大部分内容
3.给子进程分配资源。
4.复制父进程地址空间
5.将父进程设置成就绪状态,放入就绪队列。
这里写图片描述

父进程调用一次pid_t pid = fork();获得一个子进程
fork返回0是子进程,fork返回大于0的数是父进程
fork调用后父子进程之间交替进行。
ps -ef | grep a.out | grep -v grep:
查看正在运行的进程的编码,然后通过cd /proc/编码来看进程的具体内容
ls -l exe用来查看进程运行的可执行文件

孤儿进程和僵尸进程

  • 僵尸进程
    一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态那么子进程的描述符仍然保留在系统中。这种进程称之为僵尸进程。
    我们接下来尝试用代码来模拟僵尸进程的场景:
#include <stdio.h>
#include <stdlib.h>
int main()
{
pid_t id = fork();
if(id < 0){
perror("fork");
return 1;

else if(id > 0){ //parent
printf("parent[%d] is sleeping...\n", getpid());
sleep(30);
}else{
printf("child[%d] is begin Z...\n", getpid());
sleep(5);
exit(EXIT_SUCCESS);
}
return 0;
}

在上面的代码我们让父进程保持sleep状态,然后让子进程exit,那么这个子进程就是一个僵尸进程。

  • 孤儿进程
    一个父进程退出,而它的一个子进程还在进行,那么这些子进程将成为孤儿进程。孤儿进程将被init(进程号为1)所收养,并且由init进程对他们完成状态收集工作。
    子进程死亡需要父进程来处理,那么意味着正常的进程应该是子进程先于父进程死亡。当父进程先于子进程死亡时,子进程死亡时没父进程处理,这个死亡的子进程就是孤儿进程。
    但孤儿进程与僵尸进程不同的是,由于父进程已经死亡,系统会帮助父进程回收处理孤儿进程。所以孤儿进程实际上是不占用资源的,因为它终究是被系统回收了。不会像僵尸进程那样占用ID,损害运行系统。
    接下来我们尝试用代码模拟孤儿进程的场景:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t id = fork();
if(id < 0){
perror("fork");
return 1;
}
else if(id == 0){//child
printf("I am child, pid : %d\n", getpid());
sleep(10);
}else{//parent
printf("I am parent, pid: %d\n", getpid());
sleep(3);
exit(0);
}
return 0;
}
  • 僵尸进程的处理
    得出结论,孤儿进程不会占资源,僵尸进程会占用资源危害系统。我们应当避免僵尸进程的出现。
    解决办法如下:
    1)通过信号机制
      子进程退出时向父进程发送SIGCHILD信号,父进程处理SIGCHILD信号。调用wait()或者waitpid(),让父进程阻塞等待僵尸进程的出现,处理完在继续运行父进程。
    2)杀死父进程
    当父进程陷入死循环等无法处理僵尸进程时,强制杀死父进程,那么它的子进程,即僵尸进程会变成孤儿进程,由系统来回收。
    3)重启系统
    当系统重启时,所有进程在系统关闭时被停止,包括僵尸进程,开启时init进程会重新加载其他进程。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值