1.进程状态
一般操作系统的进程状态如下,各个具体的操作系统都会包含但可能实现的具体方式不同
1.1运行状态--R
cpu会维护一个运行队列来通过调度器挑选合适的进程放入cpu中运行,已知管理进程就是管理pcb,将它们用双向列表维护起来放入运行队列中获取头尾指针进行查找.已经在cpu中运行的进程状态为R,但只要存在于运行队列中,代表进程已准备好可以随时被调度,就称之为运行态R
时间片概念
一个进程不是放到cpu中一直执行完毕才会把自己放下来,若这样来一个无限循环那么其他进程就无法运行了电脑就只能一直显示循环,所以为了避免这种状况引入时间片概念,在pcb中操作系统会为每个进程分配,时间片不是固定,可能在不同操作系统,优先级,系统负载下都会发生动态变化.
所以当一个进程在cpu上执行达到时间片限制就会执行下一个,在同一个时间段内所有的进程代码都会被执行,称为并发执行.由于cpu执行速度很快我们无法准确感知,会认为所有进程一起运行,其实存在大量的进程切换
对进程管理实际上是对软件进行管理因为进程内有对应的代码和数据
1.2阻塞状态
首先了解管理硬件资源也是先描述再组织,一定有对应的结构体信息像进程的pcb一样方便被管理,每一个设备的结构体中都有等待队列,当进程中所想访问的软硬件资源没有就绪时,进程的pcb就会由操作系统调度到所依赖的软硬件资源的等待队列中排队等待,等到就绪后才会放到运行队列中
等待队列与运行队列的区别:
等待队列:按资源类型划分(每个资源一个队列),存放因等待该资源而阻塞的进程 PCB;
运行队列(就绪队列):按CPU 核心划分(每个核心一个队列),存放已就绪、等待获取 CPU 的进程 PCB。
1.3(阻塞)挂起状态
每个进程都要占用内存资源的,如果阻塞队列过多,那么闲置的进程就过多占用的内存资源也就越多,当操作系统内存资源严重不足我们需要在保证正常运行的情况下省出来一些空间
如何节省空间
将进程的代码和数据部分暂时存入到外设中,叫换出,此时进程中只有pcb保存,每个阻塞状态的进程都如此,因此节省了很多空间,此时进程的状态称为挂起,当需要被运行时会把存入外设中对应的代码和数据放回到进程当中,叫换入
2.具体Linux进程状态
- R (running)运行态:
并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列
里。
1.事例理解:
当写一个带有printf语句的无限循环语句的可执行文件,文件的状态为S,因为输出要访问显示器设备,设备不一定处于可以直接被写入的状态,所以进程有很大概率在进行等待.但我们观察到显示器一直在输出,而在内存中可能一直在等待io设备就绪,我们不能用主观感受去判断cpu的速度.
2.当去掉printf打印语句后就是纯运行状态,没有io,状态就变为R
3.注意细节:ps 命令就是拿到执行的这一瞬间,所有的进程的状态,拿到信息之后再通过管道给grep进程,那么在ps截取所有进程状态的这一瞬间,可能grep还没有执行到管道的阻塞读取(等待进程写入管道信息),所以他这个时候是R状态,也有可能他执行到了管道读取,那么他就是S状态,因为在读取之前还要进行参数解析等前置工作.
4.R+中+是指前台运行,即执行指令期间bash命令行不再工作,./可执行文件 & 是后台运行,进程运行期间还可以输指令,前台进程用CTRL+c结束,后台要用kill -9 pid结束
- S睡眠状态(sleeping):
意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep)),对应一般操作系统进程中的阻塞状态
- D磁盘休眠状态(Disk sleep):
有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的
进程通常会等待IO的结束。
1.进程处于该状态时,正在等待某个不可中断的 I/O 操作完成(如磁盘读写、网络设备响应、硬件驱动交互等)。
2.本质:内核为了保证 I/O 操作的原子性和数据一致性,禁止该进程被信号或外部事件中断。此时进程 "深度睡眠",完全由内核控制,直到 I/O 操作完成后自动退出该状态。就是为了避免内存资源紧张时的进程在等待IO操作结果信息时被操作系统误删从而可能导致数据丢失的问题
- T停止状态(stopped):
1.可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。kill -l指令可以查看号,18,19号可以赞同和继续进程
2.T状态可以理解为休眠状态,但应用场景不同,有可能在等待资源相应,也有可能在控制进程不让某个进程运行即暂停,应用场景如gdb调试时遇到断点停下
但S一定是等待某种资源就绪
- X死亡状态(dead):
这个状态只是一个返回状态,不会在任务列表里看到这个状态。
- Z(zombie)-僵尸进程:
僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用,后面讲)没有读取到子进程退出的返回代码时就会产生僵死(尸)进程僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态
子进程退出后父进程还在运行没有读取其返回代码,变为Z状态直到父进程去读取,若父进程退出则被收养
父进程结束后没有僵尸进程是因为立马被bash进程回收,每个进程都有自己的父进程,每个父进程只对自己的子进程负责,操作系统都可以负责
危害:
维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态一直不退出,PCB一直都要维护.
若很多子进程都不回收会造成内存资源的浪费和泄漏问题
- 孤儿进程
父进程先退出,子进程就称之为"孤儿进程",孤儿进程被1号init进程领养,当然要有init进程回收
systemd 是 Linux 系统启动后创建的第一个用户态进程,其进程 ID(PID)固定为 1,它是所有其他用户态进程的 "祖先",也被称为 "初始化进程(init 进程)",负责后续所有用户态进程的启动和管理(相当于系统的 "总管家")。在传统 Linux 系统中,这个进程是 init(如 SysV init);而现代 Linux 发行版(如 Ubuntu 16.04+、CentOS 7+、Debian 9 + 等)已普遍用 systemd 替代传统 init,因此 systemd 成为了 PID=1 的进程。
top 是 Linux 系统中最常用的实时进程监控工具,能够动态显示系统资源(CPU、内存、进程等)的使用情况,帮助用户快速定位系统负载过高、资源占用异常等问题。
Linux中最基本的关系为父子关系,决定了整个pcb的目录结构为多叉树关系,pcb中可存在多个信息以便被多种数据结构维护起来
3.进程优先级
3.1基本概念
区分:
权限:指能否访问一个资源
优先级:对于资源的访问先后问题
为什么分优先级:
1.因为资源是有限的,进程是多个的,注定了进程之间是竞争关系,操作系统为了保证进程之间的良性竞争,确认优先级
2.如果进程长时间得不到cpu资源,该进程代码长时间无法推进,造成该进程饥饿问题
作用:
1.优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可能改善系统性能。
2.还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能
3.2PRI和NI
PRI :即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小
进程的优先级别越高
NI :为nice值,其表示进程可被执行的优先级的修正数值
注意:进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。
加入NI修正后PRI(new)=PRI(old)+nice,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行所以,调整进程优先级,在Linux下,就是调整进程nice值优先级可以被调整,更改nice值,说明进程可以被我们一直调度,但Linux不想过多的让用户参与优先级的调整,所以限制了范围,nice其取值范围是-20至19,一共40个级别
3.3top命令更改nice值
输入top指令,进入top后按"r"-->输入进程PID-->输入nice值,再通过ps指令查看
注意:
1.普通用户无法更改优先级
2.当更改nice值超出范围时会以范围值来计算
注意:
1.Linux 内核在处理用户身份和权限时,确实只识别数字形式的UID(用户 ID) 和GID(组 ID),而我们看到的 "用户名""组名" 只是这些数字的 "人类友好别名".内核处理权限(如文件访问、进程运行)时,效率优先,数字比对(UID/GID)比字符串匹配(用户名)更快。
2.文件名以字符串形式存储在文件系统(如 ext4、xfs)的 inode 结构中,系统通过字符串精确匹配查找文件
3.ls -n可以查看用户的uid
3.4操作系统如何根据优先级开展的调度
1.每一个进程中都有一个运行队列,其中有大小140比特位的task_struct指针数组来存贮对应进程的pcb信息,指针数组中只用到[100,139]位来按优先级存储进程pcb信息,这其实是一个开散列的哈希做法
2.同样优先级的进程在同一位置排队,形成一个个哈希桶,调度顺序按从左往右,从上到下
3.当进行调度时又有新进程加入时一进一出影响调度效率所以用一个waiting镜像数组来维护更改变化的信息
4.定义两个指向task_struct指针的指针,一个指向运行队列,一个指向等待队列,cpu调度进程时通过该指针找到指针数组再找到相应优先级的进程
5.当运行队列中进程运行完后,交换run和wait双指针,这样等待队列中的进程就可以被运行,如此循环往复
6.通过对应数组大小的位图来判断队列是否为空,能达到近O(1)的调度算法.所以优先级调整的本质就是把对应的pcb链入到运行队列中哪一个下标处,就是在队列中改变pcb的存在位置
7.设计一个运行中队列和一个等待队列,可以防止一个优先级很高的队列在cpu中执行的时间片到后,重新排队但又是优先级最高的那个又要去cpu运行的循环情况发生,所以会把运行过的队列放到等待队列中重新排队,直到运行队列中那固定的一些进程运行完后再交换指针内容,让等待队列中的进程开始运行,运行过后的进程再到另一队列中排队,如此循环往复
3.5概念补充
竞争性 :
系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
独立性 :多进程运行,需要独享各种资源,多进程运行期间互不干扰
并行 :多个进程在多个CPU下分别,同时进行运行,这称之为并行
并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发