Linux之进程状态&&进程优先级详解

 更新时间:2025年02月06日 17:11:18   作者:阿赭ochre  
文章介绍了操作系统中进程的状态,包括运行状态、阻塞状态和挂起状态,并详细解释了Linux下进程的具体状态及其管理,此外,文章还讨论了进程的优先级、查看和修改进程优先级的方法,以及并发相关的概念和函数的返回值

一、操作系统的进程状态

1.1运行状态

  • 当一个进程准备就绪,获得了CPU资源,就会在CPU所维护的运行队列上等待CPU的调度
  • 一个进程在运行或者处于运行队列中,都叫做运行状态
  • 一个进程并不是一直在CPU上执行的,而是会以进程切换的方式,在一段时间内,使多个进程同时被推进---并发
  • CPU对进程的调度是基于进程切换和时间片轮转的调度算法

1.2阻塞状态

  • 当一个进程正在等待某种IO事件的完成,实际上就是在等待获取某种资源,那么该进程就处于一种阻塞状态
  • 操作系统对软硬件资源进行管理,都要遵循“先描述再组织”的原则,操作系统对外设的管理就是在内存中创建一个个的外设数据结构对象,再用链表的方式组织起来
  • 每一个外设的pcb数据结构对象都会包含一个等待队列,当一个进程在获取某种外设资源时(比如scanf),外设资源还未准备好,该进程就会链入该外设的pcb等待队列进行等待,此时进程就处于阻塞状态,直到资源准备就绪,才会被链入运行队列等待CPU调度,将状态S改为R

1.3挂起

  • 当进程在队列中排队,操作系统的资源严重不足或者操作系统需要给新加入的进程提供空间,那么此时操作系统就会将正在等待排队的进程所对应的数据和代码换出到外设分区中,等到该进程被调度了再换入给该进程
  • 从换出到换出的过程,进程处于挂起状态

二、Linux下具体的状态

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 */
};
  • R就是操作系统中进程的运行状态:并不意味着该进程一定在运行中,它表明该进程要么在运行要么在运行队列中
  • S和D状态都对应操作系统中的阻塞状态:S是一种浅度睡眠,可以被唤醒;D是一种深度睡眠,不会响应任何请求
  • 当一个进程正在进行某种IO事件,比如在向磁盘写入重要数据的时候,它必须等待磁盘写入完毕将写入结果反馈给进程,再反馈给上层用户,但如果这时候操作系统的资源严重不足,进程挂起已经没办法解决问题了,操作系统就会选择杀掉进程,如果一个进程在等待磁盘写入完毕的期间被杀掉,那么就会导致数据的丢失!为了防止这种情况,必须给该进程一个标识符--D,告诉操作系统我这个进程在等待磁盘写入完毕的期间是不能被杀掉的
  • T停止状态:可以通过发送SIGSTOP来停止进程,可以发送SIGCONT来让进程继续运行,当一个进程想要获取某种资源或者被其他进程控制(如gdb),就可能会出现T状态

  • R就是操作系统中进程的运行状态:并不意味着该进程一定在运行中,它表明该进程要么在运行要么在运行队列中
  • S和D状态都对应操作系统中的阻塞状态:S是一种浅度睡眠,可以被唤醒;D是一种深度睡眠,不会响应任何请求
  • 当一个进程正在进行某种IO事件,比如在向磁盘写入重要数据的时候,它必须等待磁盘写入完毕将写入结果反馈给进程,再反馈给上层用户,但如果这时候操作系统的资源严重不足,进程挂起已经没办法解决问题了,操作系统就会选择杀掉进程,如果一个进程在等待磁盘写入完毕的期间被杀掉,那么就会导致数据的丢失!为了防止这种情况,必须给该进程一个标识符--D,告诉操作系统我这个进程在等待磁盘写入完毕的期间是不能被杀掉的
  • T停止状态:可以通过发送SIGSTOP来停止进程,可以发送SIGCONT来让进程继续运行,当一个进程想要获取某种资源或者被其他进程控制(如gdb),就可能会出现T状态

子进程退出,父进程没有退出并且没有回收子进程的退出信息,就会使子进程进入僵尸进程

  • 孤儿进程:当子进程还没退出,父进程就已经推出了,那么该子进程就会被1号进程(操作系统)领养,此时的子进程就叫做孤儿进程。
  • 为什么要被1号进程领养?
  • 为了让子进程在退出的时候可以被回收退出信息。此时退出进程不能再用Ctrl C 而应该使用kill -9 杀掉进程

三、进程的优先级

3.1基本概念

  • CPU的资源是有限的,但是进程是多个的,这就注定了进程之间存在竞争关系
  • 为了保证进程被CPU调度的公平和良性竞争,就必须引入进程优先级的概念
  • 进程优先级是指CPU分配资源的先后顺序(访问资源的先后顺序)
  • 如果一个进程长时间无法访问到资源,代码无法被推进,就会导致该进程的饥饿问题
  • 优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可能改善系统性能
  • 还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整 体性能

3.2查看进程优先级的命令

  • 使用 ps -al

  • UID: 代表执行者的身份
  • PID: 代表这个进程的代号
  • PPID:代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
  • PRI:代表这个进程可被执行的优先级,其值越小越早被执行
  • NI :代表这个进程的 nice 值

PRI即进程的优先级,通俗点说就是程序被CPU执行的先后顺序,此值越小

进程的优先级别越高(默认80)

NI就是nice值,其表示进程可被执行的优先级的修正数值

PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice

这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行

所以,调整进程优先级,在Linux下,就是调整进程nice值 ,Linux为了保证优先级的调整范围,nice其取值范围是-20至19,一共40个级别

3.3修改进程优先级的命令

  • 使用top r + 进程pid + 修正的nice值

操作系统是如何根据优先级展开调度的呢?

CPU会维护一个runqueue,runqueue中有两个调度队列,他们本质上是两个指针数组,存储40个优先级所一一对应的40个队列的指针,再结合位图的思想(调度完毕的队列为0,未调度完毕的队列为1),针对不同的优先级对进程进行调度!

新加入的进程或者被进程切换下来的进程会链接到另外一个调度队列的对应的优先级的队列当中去,直到前一个调度队列全部调度完后,swap交换两个队列的指针,对另外一个未调度的队列进行调度,以此循环往复,也叫Linux内核的O(1)调度算法

3.4其他概念

  • 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
  • 独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰
  • 并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行
  • 并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发

3.5并发

  • 函数的返回值是如何被外部拿到的?----通过CPU寄存器
  • 系统如何得知我们当前进程执行到哪一行代码?----通过pc(eip)程序计数器,记录当前进程执行的指令的下一条指令的地址
  • CPU中的寄存器很多!将进程中的高频数据放入到CPU的寄存器中可以提高效率
  • 问题是,我们在进行进程切换到时候,如果不把属于当前进程的存储在寄存器中的数据带走,那么下一个来的进程在把数据放入寄存器的时候就会将上一个进程的数据覆盖,等到该进程重新被CPU调度,就无法从上一次执行的位置继续往下执行
  • CPU的寄存器中保存的是进程的临时数据,也叫进程的上下文
  • 一个进程在被CPU高频调度的时候,必须经历调度----排队,在这个过程中,进程离开CPU必须自己保存上下文带走,再被调度时恢复上下文
  • 总之,进程切换涉及到保存上下文和恢复上下文,寄存器中的数据在被保存时实际上是以结构体的形式被保存在内存中,进程的pcb数据结构对象中存在一个指向该结构体的指针

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • CentOS 7 虚拟机无法开机问题的快速解决方法

    CentOS 7 虚拟机无法开机问题的快速解决方法

    这篇文章主要介绍了CentOS 7 虚拟机无法开机问题的快速解决方法,非常不错,具有一定的参考借鉴价值,感兴趣的朋友一起看看吧
    2016-11-11
  • Ubuntu中实现定时唤醒与自动休眠功能

    Ubuntu中实现定时唤醒与自动休眠功能

    在自动化脚本执行的时间段内唤醒系统使其正常运行,其余时间则让其进入休眠状态,以此来降低能耗,为达成这一目标,我编写了一个简易的脚本,并通过 crontab 配置了自动化任务,接下来,我会详尽地讲解整个配置过程,需要的朋友可以参考下
    2024-09-09
  • linux缩减XFS分区格式的根目录

    linux缩减XFS分区格式的根目录

    大家好,本篇文章主要分享的是linux缩减XFS分区格式的根目录,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • centos7系统下搭建docker本地镜像仓库的方法

    centos7系统下搭建docker本地镜像仓库的方法

    本篇文章主要介绍了CentOS 7 : Docker私有仓库搭建和使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-02-02
  • 浅析在 RHEL8 配置静态 IP 地址的不同方法

    浅析在 RHEL8 配置静态 IP 地址的不同方法

    如果一个人在 Linux 服务器上正确配置了静态地址,那么他/她就可以通过网络远程访问它。在本文中,我们将演示在 RHEL 8 服务器网卡上配置静态 IP 地址的不同方法,需要的朋友可以参考下
    2019-09-09
  • Linux工具之Nethogs按进程监控网络带宽的安装部署

    Linux工具之Nethogs按进程监控网络带宽的安装部署

    NetHogs是一个小型的net top工具,不像大多数工具那样拖慢每个协议或者是每个子网的速度而是按照进程进行带宽分组,这篇文章主要介绍了Linux工具Nethogs按进程监控网络带宽,值得收藏,需要的朋友可以参考下
    2019-07-07
  • Linux之信号的保存方式

    Linux之信号的保存方式

    这篇文章主要介绍了Linux之信号的保存方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-02-02
  • Linux之多线程以及多线程并发访问同一块内存的处理问题

    Linux之多线程以及多线程并发访问同一块内存的处理问题

    这篇文章主要介绍了Linux之多线程以及多线程并发访问同一块内存的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Shell中的单中括号和双中括号的用法详解

    Shell中的单中括号和双中括号的用法详解

    shell中的中括号在条件测试中是使用最频繁的,无论是中括号还是双中括号,可用于一些条件的测试:算术比较、文件属性测试、字符串比较。这篇文章主要介绍了Shell中的单中括号和双中括号的用法详解,需要的朋友可以参考下
    2022-12-12
  • linux日志审计服务auditd占用内存过大的解决过程

    linux日志审计服务auditd占用内存过大的解决过程

    文章介绍了如何使用ps命令查看auditd服务的内存使用情况,并提供了当auditd服务内存占用过大时的解决方法,包括在auditd.service文件中增加MemoryLimit限制并重启服务
    2025-10-10

最新评论