一:僵尸进程
小辉:僵尸?好可怕啊。
小黑:别怕,这里的僵尸不是电视中的
僵尸奥.你看完它的介绍就明白了,为
啥叫他僵尸进程
1.1:成因:
- 子进程结束之后,父进程没有回收掉子进程的资源而产生的进程
- 示例代码
#include<stdio.h>
#include<unistd.h>
int main(){
pid_t pid=fork();
if(pid>0){
printf("father:%d,ppid:%d\n",getpid(),getppid());
while(1){
sleep(1);
}
}else if(pid==0){
printf("child:%d,ppid:%d\n",getpid(),getppid());
int count=3;
while(count>0){
sleep(1);
count--;
}
}else{
perror("fork");
}
return 0;
}
1.2:危害:
- 父进程交给子进程的任务,子进程完成后需要父进程回收执行结果,但是父进程一直没有回收子进程的资源,所以子进程一直等待着父进程回收资源。
- 维护退出状态需要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说Z状态一直不退出,PCB一直都要维护。
- 一个父进程创建很多个子进程,就是不回收,是不是就会造成内存资源的浪费.处理不当会造成内存泄漏
1.3:处理方式
- 直接kill 僵尸进程是kill 不掉的,可以kill 掉僵尸进程的父进程。更科学的处理办法是: 进程等待
1.4:为什么 kill 父进程僵尸进程没了?
- 当 kill掉父进程之后,子进程就称为孤儿进程,孤儿进程会被1号进程收养,从而回收资源
小辉:奥,原来是这样的啊.
只是父进程没有回收掉子进程的资源
才导致僵尸进程的产生啊
二:孤儿进程
小辉:小黑,为啥进程还有孤儿呢?
好可怜奥.
小黑:创造它的父进程虽然比他早结束,
但是它会被1号进程收养的.别担心
2.1:进程的状态
小辉:大家仔细看,什么是1号进程奥
- 当kill 掉父进程之后,子进程就被称为孤儿进程,孤儿进程会被 1 号进程(init进程)收养,从而释放资源
- 孤儿进程不是一种状态,是指父进程先结束了,但是子进程还在,子进程的父进程变成了1号进程
- init进程:开机时运行的第一个进程
代码示例
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
int main(){
pid_t pid=fork();
if(pid>0){
printf("father pid:%d,ppid=%d\n",getpid(),getppid()) ;
sleep(9);
printf("------parent going to die------------\n");
}else if(pid==0){
while(1){
printf("child pid:%d,ppid=%d\n",getpid(),getppid() );
sleep(1);
}
}else{
perror("fork");
return 1;
}
return 0;
}
- 运行结果
小辉:因为写了死循环,这个子进程会一直
执行,但是不要方,有办法解决奥.
因为有死循环的存在,所以子进程不能结束。需要另外打开一个终端,从新打开的终端 kill 掉子进程才可以
2.2:组织进程
- 双向链表进行组织,每个结点就是一个task_ struct (只针对Linux)
2.3:除了ps 之外top也可以查看进程的状态
-
PR:数字越小,优先级别越高
-
NI(nice):优先级的修正值,PR+NI => 最终的PR
-
通过指令可以调整nice,宏观上往往看不出效果