OS 调度哪个进程(或者说给哪个进程分配资源),都是有依据的
这里的依据就是今天要说的两个东西
1、进程状态 :哪个进程适合运行(如,休眠的进程不需要分配资源!)
2、进程优先级:哪个进程优先运行
目录
一、进程状态
1、事件发生的几种状态
2、进程的状态分类
(1) R 运行状态
(2) S 睡眠状态
(3) D 磁盘休眠状态
(4) T 停止状态
(5) X 死亡状态
3、进程的异常状态
(1) 僵尸进程
(2) 孤儿进程
(3) 僵尸进程的危害
二、进程优先级
1、优先级的概念
2、Linux系统中的优先级
3、修改nice值
查看进程状态:ps ajx
(1) 就绪态
处在运行队列中,但是不在运行的进程
(2) 运行态
处在运行队列中,同时在运行中的进程
运行队列中每个进程都会有自己的时间片,
时间片结束后,若进程未运行完,自动排到队尾,让下一个进程运行;若进程运行完了,则从运行队列中剥离
详情可以参考进程(一)—— 进程的创建和程序的运行过程_abs(ln(1+NaN))的博客-CSDN博客
(3) 等待态
处在等待队列中的进程:可以看作是等待态
问:什么是等待队列??
答:程序中的用户输入、死循环等,占用了CPU资源,但是没有干任何有意义的事,这个时候,OS会把这些进程丢到等待队列中,等需要用到CPU资源的时候,再加入到运行队列中
运行队列 ——> 等待队列:当CPU 中某个进程需要等待输入时,CPU会把这个进程丢到等待队列
(这个过程叫“挂起”)
等待对垒 ——>运行队列:当 等待队列中的 进程,可以读取键盘输入时,状态修改为 R,进入到
CPU 的运行队列
(这个过程叫“唤醒”)
进程状态的分类大致可以分为这三种,但这三种还能继续细分
表示当前进程在运行队列中或者正在运行
进程在等待事件的完成,可以归为等待状态的一类(该状态可以被中断,然后切换到其他状态)
也叫做“ 深度睡眠状态 ”(该状态下的进程无法被立即中止,即便是OS也无法中止该进程)
为什么会存在这种状态呢??
下面举个例子
假设某个进程在向磁盘传输数据,这个时候,OS路过,发现进程在休眠,于是该进程被kill了
磁盘存好数据以后,发现进程没了,数据传输的结果不知道应该给谁?
这个时候是谁的问题? OS ?进程 ?
为了避免OS误杀,如果进程处于D状态,OS也无法中止这个进程,只能等待IO结束
发送SIGSTOP信号给进程来停止进程
暂停的进程可以发送SIGCONT信号让进程继续运行
kill -l:查找暂停信号
kill -19 进程pid:给pid为xxx的进程发送暂停命令
(19号是暂停信号)
kill -9 进程pid :如果Ctrl+C无法杀掉进程,可以通过这个指令杀掉
这个状态只是一个返回状态,无法在任务列表中观察到
上述所说的,都是进程的正常状态,但是存在两种异常状态,会对内存造成影响
僵尸可以理解为僵化的尸体,僵化的尸体不作处理,就会危害到周围环境
什么时候会出现僵尸进程呢?
原本子进程运行完,会进入“死亡”状态,需要父进程回收(获取子进程的退出码)
但是!!此时父进程在忙自己的事,子进程“死亡”以后,无人回收,一直在占用资源
此时的子进程就是僵尸进程
孤儿可以理解为没有双亲
为什么会出现孤儿进程??
当父进程先退出了,也就是“死亡”了,只留下孤零零的子进程,没人回收
这个时候,子进程就会变成孤儿进程
但是不要紧,父进程先退出了,子进程会被1号Init进程领养,也就是回收
子进程退出,父进程在忙,此时子进程无人回收,一直在占用资源
- 进程控制块(PCB)也要一直维护这个进程
- 创建的task_struct(PCB) 也要一直占用内存
这样会造成很多内存泄漏!!!
优先级指的是 CPU分配资源的先后顺序
优先级高的进程 拥有优先执行的权利,对于多任务环境来说,配置优先级很有用
查看系统进程:ps -l
PID:当前进程的pid
PPID:父进程的pid
PRI:当前进程被执行的优先级,值越小,越早被执行
NI:代表这个进程的nice值,指的是优先级的修正值
PRI我们知道,是优先级,那么nice值是什么?有什么作用呢?
举个简单的例子,一个囚犯被判刑10年,但是监狱根据他的服刑表现,减刑2年,所以这个囚犯的最终服刑时间是8年
这里也是同理,PRI = 最初判刑时间10年,NI = 修正服刑时间 -2 年
所以最终的优先级PRI(new) = PRI + NI
其中 NI 的取值范围为 -19 ~ 20
一般情况下,初始优先级PRI = 80,NI = 0
如果要修改PRI,修改NI即可(一般不建议修改)
什么是进程饥饿?
当进程长时间得不到资源时,就会发生“进程饥饿”问题!
假设当前进程占用CPU资源较多,如果我们把NI调整为-19,提升了当前进程执行的优先级,会导致其他进程分配不到资源或者分配的资源较少,容易出现进程饥饿的情况
注意:
假设最初的PRI=80
第一次设置NI = 10,则最后PRI = 80+10 = 90
第二次设置NI = -10,则最后的PRI = 80-10 = 70
由此可知,每次设置NI,PRI都不会在上一次的基础上修改