12 状态优先级

概念

cpu需要执行很多进程,有很多进程排在队列中,每个进程加载后运行一定的时间段,然后切换下一个进程。cpu如何判断进程需不需要加载,什么时候加载,依靠进程的状态和优先级属性来判断,进程调度,就变成了在task_struct的队列中选择一个进程的过程

内核源码

为了弄明白正在运行的进程是什么意思,需要知道进程的不同状态,一个进程有几个状态,有时候也叫任务

/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};

新建:新建进程,还没有运行的时候

运行

阻塞:当一个进程被cpu执行时,需要磁盘、网卡、显卡等设备资源就绪才可以,就会进入其他队列等待,等待磁盘等资源就绪的队列就是阻塞队列。**等待非cpu资源就绪就叫做阻塞态。**比如一个scanf函数一直不输入,等待键盘资源,就是阻塞。程序卡死有时候也是等待网卡资源,也有可能是cpu被占用,得不到调度,或操作系统卡死

在这里插入图片描述

挂起:当内存不足的时候,OS通过适当的置换进程的代码和数据到磁盘,进程的状态就叫做挂起
cpu内存不足的时候,会将长时间不执行,还需要等待很长时间资源的进程代码和数据换出到磁盘。也就是电脑的swap分区,是操作系统预先留好的,保证cpu正常的运行,这时候cpu会比较慢。再回来运行时需要把数据拿回来才能正常运行。压力过大电脑会宕机

写一份循环代码,用上节的循环命令不断查看进程状态
在这里插入图片描述

R+的状态就是运行中,接着往循环内加一个printf或者scanf函数,cpu的执行速度是非常快的,大部分时间都是往屏幕打印等待键盘输入等阻塞状态

在这里插入图片描述
S的状态就是阻塞

+的意思是前台程序
**前台进程:**当这个程序运行的时候,输入其他命令就没作用
运行程序后面加一个&符号,表示在后台运行,这个时候就没有+号了

在这里插入图片描述后台进程停止需要发送kill信号,crtl+c没用
在这里插入图片描述

退出状态:

有了上面的状态描述,下面逐个解析源码对应的状态:

R运行状态(running):对应上面的运行态
S睡眠状态(sleeping):阻塞状态,可中断睡眠
什么是可中断睡眠,运行一个阻塞状态的程序,-l查看所有信号
在这里插入图片描述
发送19号停止信号
在这里插入图片描述
进程被强制停止了,也就是睡眠状态还会接受命令,可以被中断

D睡眠状态:深度睡眠,磁盘睡眠,不可被中断,不可以自动唤醒
这个和上面的S状态相反
当服务器压力过大的时候,操作系统会将一些长时间不就绪的进程杀掉,多数为等待硬盘资源就绪的进程,当正准备往硬盘写入数据被杀掉后,就会造成数据丢失。为了防止这种情况,就设置了一种D状态,操作系统遇到这种状态就不会误杀。常用于从硬盘读取数据的场景,只有当硬盘数据就绪完成后,才会改变状态。kill信号也不行,dd命令的进程就是这种状态

T暂停状态: 上面发送了19号信号的进程就是暂停状态
在这里插入图片描述
t调试状态: 暂停状态的一种,正在调试的进程显示的状态(需要程序是debug版才可以调试),打一个断点,运行到断点处

在这里插入图片描述

X终止状态: 瞬时性非常强, 因为有很多进程在运行,需要标注可以回收的进程,很难捕捉到,任务列表李看不到

Z僵尸状态: 一个进程已经退出,不允许被OS释放,处于一个被检测的状态。一般是为了父进程或OS来回收,需要检测运行的结果

#include <stdio.h>
  2 #include <unistd.h>
  3 #include <sys/types.h>
  4 
  5 int main()
  6 {
  7     pid_t pid = fork();
  8     if (pid == 0)
  9     {
 10             sleep(3);  
 11     }
 12     else if(pid > 0)                                 
 13     {
 14         while(1)
 15         {
 16             sleep(3);
 17         }  
 18     }      
 19 }         

上面的代码子进程三秒后会结束,父进程一直在运行,可以循环查看状态
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

上图是理论状态,字母是具体状态。创建就是进程没运行,fork的子进程如果还没运行就是创建
运行状态,退出或终止就是Z和X状态,阻塞就是S,挂起也是S,看数据在不在内存,不在的话,内存中是挂起,进程状态还是S。状态可以是在上面的很多之间不停转换

僵尸状态

一个比较特殊的状态,进程退出且父进程没有读取到返回代码就会产生僵尸进程
僵尸进程会以终止状态保存在进程表中,并且会一直等待父进程读取退出状态代码
所以,只要子进程退出,父进程还在运行,但父进程没有读取到子进程状态,子进程进入Z状态

僵尸进程危害

进程的推出态必须被维持下去,要告诉关心它的父进程任务完成情况,如果一直不读取,就处于Z状态。进程不退出,PCB一直要维护,一直不回收,就会造成内存资源浪费,后面会详细说明

孤儿状态

父进程提前退出,子进程还在运行,就叫孤儿进程
孤儿进程会被1号进程领养,就是系统的 init进程,系统本身,也会回收

int main()
  6 {
  7     pid_t pid = fork();
  8     if (pid == 0)
  9     {
 10         while(1)       
 11         {        
 12      
 13             sleep(3);
 14         }                                            
 15     }
 16     else if(pid > 0) 
 17     {
 18             sleep(3);
 19             exit(0);
 20            
 21     }                
 22 } 

当3秒父进程结束后,子进程的父进程立马变成了1号进程,这时变为后台进程,可以kill杀掉
在这里插入图片描述

为什么要被领养,未来子进程退出的时候父进程不在,需要领养来回收资源

进程优先级

基本概念

cpu资源分配的先后顺序,进程的优先权
优先权高的进程有优先执行的权利,配置进程优先权对多任务环境的linux很有用,可以改善系统性能
还可以吧进程运行到 指定的cpu上,可以大大改善系统整体性能

优先级= 老优先级+nice值

运行一个进程,ps -la查看优先级
在这里插入图片描述

UID: 代表执行者的身份
PID: 进程的标识符
PPID: 哪个进程衍生来的,父进程
PRI: 进程的优先级,越小越早执行
NI: 代表nice值

NI是进程可执行优先级的修正数值,意思是可以通过根据这个值来调整优先级
加入nice值后,PRI会变为:PRI(new)=PRI(old)+nice
调整优先级,就是调整nice值
nice取值范围是-20至19,一共40个级别

进程的nice值不是优先级,但是会影响优先级,是修正数据

设置优先级

进入top,按r输入进程pid,回车后输入nice值
在这里插入图片描述
sudo模式设置nice为-100后,变为了60
在这里插入图片描述

这是因为每次设置nice值,老的优先级都是从80开始算,最小优先级是-20,80-20就是60
优先级的调整不会太大,nice值范围固定。是为了尽量不打破系统的调度安排,避免恶意占用资源,也为了系统更稳定

其他概念

竞争性:系统进程数目众多,cpu资源少量,所以进程有竞争性,为了高效合理分配资源,有了优先级
独立性:多进程运行,独享各种资源,一个进程崩溃不会影响其他进程。互相不干扰
并行:多个进程在多个cpu下同时运行
并发:进程切换的方式,一段时间内,多个进程都得以推进

每个进程在cpu中运行的时间叫时间片,而这个运行时间并不是固定的,如果运行完毕就会出去。同时,有时高优先级的进程会抢占cpu,低优先级的出让。每个进程都会较为均衡的占用cpu

在这里插入图片描述

一个进程在cpu运行的时候,寄存器内一定保存了进程的临时数据信息,寄存器有可显寄存器,还有电脑内的不可显。这些临时数据就是进程a的上下文数据,进程a被切下来时,需要带走保存自己的上下文数据。为了下次回来的时候,能恢复上去,就能按照之后的逻辑继续执行,就如同没有中断过一样。上下文数据可以有多份,分别对应不同的进程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值