在上一讲了解了进程的基本知识后,我们再次深入了解进程,了解僵尸进程,孤儿进程,以及进程的优先级问题
Z(zombie)僵尸进程
子进程退出,父进程还在运行,但是父进程没有读取子进程的退出状态,子进程就进入僵死状态。僵死进程会以终止状态保存在进程表中,并且会一直等待父进程读取退出状态码。
在这里为了方便理解我们创造一个30秒的僵尸进程
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<sys/types.h>
5 int main()
6 {
7 int ret=fork();
8 if(ret<0)
9 {
10 perror("fork");
11 return 1;
12 }
13 else if(ret==0)
14 {
15 printf(" child:%d is Z ret:%d\n",getpid(),ret);
16 sleep(5);
17 }
18 else
19 {
20 printf("father:%d is sleeping ret :%d\n",getpid(),ret);
21 sleep(30);
22 exit(EXIT_SUCCESS);
23 }
24 return 0;
25 }
我们编译运行一下
打开监视器,发现父进程处在我们设定的睡眠状态中,子进程不就处在僵尸状态下
懂得了僵尸进程,那它有什么危害呢?
内存资源的浪费!内存泄漏
我们知道进程的退出状态是要一直被维持下去的以便父进程了解子进程的情况,这就出现了一个问题,如果是僵尸状态,那么也需要一致被维持,而维护进程就要用数据维护,这属于进程的基本信息,是要被保存在PCB中的,这就导致我们的PCB一直被占用,我们又知道PCB是一个数据结构,那么它就要在内存中开辟一段空间进行存放,如果这段空间始终得不到释放,甚至随着僵尸进程的增多,被占用的空间越来越多,那是不是内存就被浪费!
孤儿进程
父进程先退出,子进程就成了孤儿进程
孤儿进程怎么办?不用担心它会被1号进程init收养,由1号进程进行回收。
同样,我们制造一个孤儿进程
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<sys/types.h>
5 int main()
6 {
7 int ret=fork();
8 if(ret<0)
9 {
10 perror("fork");
11 return 1;
12 }
13 else if(ret==0)
14 {
15 printf(" this is child:%d ret:%d\n",getpid(),ret);
16 sleep(30);
17 }
18 else
19 {
20 printf("father:%d is exit ret :%d\n",getpid(),ret);
21 sleep(5);
22 exit(0);
23 }
24 return 0;
25 }
编译执行一下
打开监视器再瞅一眼
进程优先级
在linux下我们敲ps -l会出现下面这些看不懂的数据
我们来分析一下
PID:子进程的代号
PPID:父进程的代号
UID:执行者的身份
PRI:进程可被执行的优先级,这个值越小越被优先执行
NI:进程的nice值,表示进程可被执行的优先级的修正数
那什么是进程的优先权呢?CPU分配资源的优先顺序
优先权高的进程被优先执行,配置进程的优先权对多任务linux系统可以改善系统性能
那么NI如何理解呢?
我们都知道PRI越小越被优先执行,但是加入NI这个数据就要发生改动。PRI(新)=PRI(旧)+NI
如果NI为负值,PRI新就变小,那么它的优先级就被提高,所以调整进程优先级在linux下就是调整nice值
NI的取值范围为-20~19,一共40个级别
NI值调整
1.启动前调整(开始执行程序时就指定nice值):nice -n -5 ./可执行文件
2.调正已存在的进程nice:renice
具体格式为 renice -5 -p PID
3.用top命令更改已存在的进程nice
具体步骤:top ----> r----->输入要修改的PID------>修改的NI值
进程的附加属性
竞争性:系统进程数目众多,而CPU只有少量,甚至1个,所以进程之间是具有竞争性的,也因此产生了优先级
独立性:多进程运行需要独享各种资源,多进程运行期间互不干扰
并行:多个进程在多个CPU下分别、同时进行运行
并发:多个进程在一个CPU下采用进程切换的方式,在一段时间内让多个进程都得以推进