【Linux】进程状态与进程优先级
目录
一、操作系统下的进程状态:
1、运行态:
2、阻塞态:
3、挂起态:
二、Linux下的进程状态:
1、运行状态(R):
2、浅度睡眠状态(S):
3、深度睡眠状态(D):
4、暂停状态(T):
5、死亡状态(X):
6、僵尸状态(Z):
7、孤儿进程:
三、进程的优先级:
为什么要存在优先级:
Linux下的优先级:
top命令修改nice值:
进程的性质:
一、操作系统下的进程状态:
为什么要有进程的状态:
为了让操作系统将资源进行更好的管理和调度,提高系统的效率,那么就需要给进程几个状态来帮助操作系统进行管理,操作系统通过跟踪进程的状态来控制和管理它们的执行
1、运行态:
在操作系统当中,系统刚把我们的进程创建出来,也就是将PCB,代码和数据创建出来,这个状态就叫做新建状态。当代码和数据已经执行完了,这个就叫做终止状态。而正在被调度,在CPU上运行的时候就是运行状态
首先要了解,进程正在CPU上执行,就需要把进程加载到CPU上进行执行,这样肯定会占用CPU的空间的
如下图,当进程要加载到CPU中,由于CPU是很小的,如果是毫无规则加载的,那么就肯定会影响效率,所以就用一个队列将所有即将进行运行的进程都连接起来,里面用头指针和尾指针维护整个队列(这个队列就叫做运行队列)这个时候,里面的所有进程此时就是运行态(随时都能够被调度器进行调度)
那么是怎么进行进程的调用呢?
在CPU上并不是等一个进程的代码被执行完后在执行下一个进程的,而是通过时间片进行管理的
时间片:指将CPU的运行时间分割时间间隔,每个进程被分配一个时间片,以便轮流使用CPU,比如说我分割一个时间片为10ms,这样每一个进程就会依次在CPU上进行10ms的运行时间,当运行过后就会重新插入队尾,然后依次像这样进行运行,由于每一个进程运行的时间特别短,我们是很难察觉的,所以就会以为各个进程都在被同时执行的家假象---------这种将进程加载到CPU中,然后从CPU中进行取下的过程就叫做进程切换
2、阻塞态:
正在执行的进程由于发生某些事件(如请求I/O、申请额外空间等)而暂停运行,这种受阻暂停的状态称为阻塞状态。通常将处于阻塞状态的进程排成一个队列,称为阻塞队列,在阻塞态下,进程不会占用CPU资源,因为它不能执行任何操作,它不能自行离开这个状态,直到它等待的事件被满足,(比如说有数据进行输入,申请内存成功)
数据进行输入:例如scanf中,用户迟迟没有进行输入的时候就是阻塞态
申请内存:当下载软件的时候,磁盘上空间不够,这个时候就出现内存不够,但软件下载进程又在等待中,这个时候就是阻塞态
阻塞态是操作系统调度和资源管理的重要组成部分,使操作系统高效地管理资源,确保进程在等待必要资源时不会浪费CPU时间
3、挂起态:
首先我们已经知道了进程是:描述其的PCB和对应的代码和数据构成的
当内存中剩余的内存严重不足的时候,但是又有程序从磁盘加载到内存的时候,这个时候就将其他进程的代码和数据放倒磁盘中,这样就为新的进程腾出了空间,当进程需要被恢复时,操作系统会从磁盘读取这些信息,将其重新加载到内存中
挂起到磁盘的过程通常发生在以下情况:
1、内存管理:当系统内存不足时,操作系统可能会选择挂起一些进程,将它们的状态保存到磁盘,以释放内存资源给其他进程使用
2、用户请求:用户或程序可以请求挂起某个进程,以便在需要时恢复它
3、系统休眠或休眠模式:在系统进入休眠模式时,所有活跃的进程可能都会被挂起到磁盘,以便在系统唤醒时恢复
这种将内存里的资源挂到磁盘中的方法可以在内存资源紧张时提供额外的灵活性
二、Linux下的进程状态:
进程是何种状态,取决于此进程的PCB在哪个队列中进行排队
1、运行状态(R):
如上是一个进程,将这个进程运行起来,然后用指令进行观察:
如上,S是接下来讲的休眠状态,那么我已经运行了,但是为什么是休眠状态呢?
其实,当前进程是已经运行了,但是在运行的时候我们很难看到,毕竟cout打印在屏幕上是非常耗时的,但是CPU运行的速率是很快的,所以在大多数时间都是在等待打印,所以就看到的是S状态
当我们将打印语句和睡眠语句屏蔽后,进程不用在等待队列中排队,CPU 就一直在处理死循环,此时可以观察到运行R状态
这个+是指的是在前台运行,也就是当前窗口运行,此时如果输入其他指令是无法读取的,退出就是ctrl+c即可,如果没有+就是指进程在后台运行的
注意:Linux中后台进程只能通过kill -9杀掉而不能够通过热键ctrl+c杀掉,热键ctrl+c杀掉的是前台进程
为啥要有前台进程和后台进程:前台进程直接接受你在键盘上的信号,并且来说,这两种情况是必须要有的,如果只有后台进程,就没法正常交互,如果只有前台进程,那么就只会有一个进程
2、浅度睡眠状态(S):
S状态其实就是阻塞状态,意味着该进程正在等待某件事情的完成,处于浅度睡眠状态的进程随时可以被唤醒,比如上述出现的S就是CPU计算太快了, 而打印太慢了(毕竟CPU的运算时间是纳秒级别的,而外设的运行时间级别是毫秒级别的)从而导致CPU一直在等待打印完成,这个时候进程就是处于阻塞状态,
3、深度睡眠状态(D):
当进程正在从内存中向磁盘中写入数据的时候,这个时候此时进程如果处于S状态,然后如果在资源紧张,操作系统关闭,或者父进程终止等等情况下有可能这个S的进程会被操作系统干掉,但是此时如果数据写入失败,磁盘返回给进程的时候发现进程没有了,这样数据就丢失了,为了防止这种情况,就将这种在等待其他资源的写入的进程设置成深度睡眠状态,这样就让操作系统不能够杀掉这个进程。
但是这个状态一般不会很长,如果长时间是D状态,那么操作系统一般就挂了
4、暂停状态(T):
指令kill:
在Linux中kill命令只要用于向进程发送信号(关于信号后面会专门讲的)进而控制进程的行为,可以使用kill -l来进行进程的查看,比如kill -9 就可以杀死某个进程,18和19信号就可以继续/暂停进程
-9杀死进程
-19暂停进程
-18继续进程
这个时候就成为了后台进程,就不能够使用ctrl+c杀掉,需要使用kill -9 杀掉
5、死亡状态(X):
Linux中的死亡状态是一个返回状态。在Linux系统中,进程结束时会进入死亡状态,这个状态表示进程已经结束,但不会在任务列表中显示
6、僵尸状态(Z):
在进程死亡之前,在等待其的退出信息被读取,这段时间该进程就处于僵尸状态,这个状态会占用内存资源,这个进程被称为僵尸进程,毕竟有内存资源被占领,所以就需要父进程读取到了子进程的退出信息之后进行回收,一般在bash下终止它的进程,bash会进行回收的,我们一般创建的父子进程可以看到僵尸进程:
#include<iostream>
#include<unistd.h>
using namespace std;
int main()
{
pid_t id = fork();
if(id == 0)
{
while(1)
{
printf("子进程正在执行,pid = %d,ppid = %d,num = %d\n",getpid(),getppid(),num);
sleep(1);
}
}
else if(ret > 0)
{
while(1)
{
printf("父进程正在执行,pid = %d,ppid = %d\n",getpid(),getppid());
sleep(1);
}
}
else
{
}
return 0;
}
如上,我们可以看到,当子进程经过5秒退出的时候就会进入僵尸状态(因为在父进程中没有对子进程进行处理),所以进程一般退出的时候,如果父进程没有主动回收子进程信息,子进程就会一直让自己处于僵尸状态,进程相关的资源尤其是:task_struct 结构体就没有被释放
危害:
虽然僵尸进程不执行任何代码,也不会占用CPU时间,但它们会占用一定的系统资源,如果系统中存在大量的僵尸进程,就可能会导致系统资源的浪费和性能下降,如果不对僵尸进程进行回收就会一直占用资源,这样就会导致内存泄漏
7、孤儿进程:
将代码改成上述所示,这就是父进程过几秒就会被回收,但是子进程却会一直进行
如上所示:
当父进程被回收之后,但是子进程还在跑,这个时候子进程的父进程就会变成pid为1的父进程,那么这个pid为1的父进程是什么呢?
通过top命令可以看到pid为1的为操作系统,所以父进程如果被终止,它的子进程仍然会运行。但是子进程的父进程会变成操作系统,因为如果不将子进程的父进程变为操作系统的话,那么当子进程结束之后就会是僵尸进程,这样会占用内存资源造成内存泄漏,因此就会被操作系统进行“领养”
三、进程的优先级:
与进程权限的区别:
进程权限是决定这个进程能不能被访问,而优先级是进程被访问的先后问题,
就像你有没有资格在你的学校吃饭(有权限在你的学校吃饭)和你吃饭时需要进行排队(先来后到的优先级问题)
为什么要存在优先级:
毕竟CPU里面的空间很小,所以各个进程之间就会有竞争关系,如果没有优先级,那么就可能会有进程长时间得不到CPU资源就会引发饥饿问题,进而这个进程不能够进行推进就会崩溃(对应Windows就是有时候鼠标变成一个蓝色的圈,然后当前进程变白,之后出现结束进程还是等待)
需要存在进程优先级,保证进程之间是良性竞争,来确定进程获取CPU资源的先后顺序
Linux下的优先级:
可以使用指令ps -al来查看进程的优先级
如上看三个地方:
UID:代表执行者的身份
PRI:代表这个进程可被执行的优先级,其值越小越早被执行
NI:代表这个进程的nice值
执行者的身份如何看:
可以使用ls -n将ls -l的名字换成编号,这个编号就是上述的UID
PRI:
这个全称是priority,这个指的是操作系统在调度进程的时候赋予的优先值,PRI值越小,该进程优先级越高,越早被执行,默认值是80
NI:
这个全称是nice,默认值是0,指的是进程的优先级调整值,用于控制进程在系统中的调度顺序,nice值的范围是从-20(最高优先级)到19(最低优先级),较高的nice值表示较低的优先级,而较低的nice值表示较高的优先级
所以一个进程的优先级的值就是 PRI + NI 的值
top命令修改nice值:
首先输入sudo top(这里毕竟是修改属性,需要root权限)后进入任务管理器,然后在按r,这样之后就会要你输入需要修改进程的pid,按回车之后就需要输入修改之后的nice值[-20 ~ 19]就可以了
进程的性质:
竞争性:由于进程的数量一般会很多,但是CPU一般只有一个,并且CPU的大小也很小,这样就会导致各个进程之间存在竞争关系(都想更多的占有CPU资源)
独立性:多进程运行期间是互不干扰,比如说在同一个电脑中当QQ这个进程崩了之后,其他进程如微信,浏览器等不会受其影响
并行:两个或者多个进程在多个CPU下分别同时进行运行,这称之为并行。
并发: 多个进程在一个CPU下采用通过时间片,利用进程切换的方式,在一段时间之内,让不同的进程同时推进的过程,称之为并发