【Linux】深入理解进程状态、优先级和调度:Linux 内核中的实现原理探析

前言

在计算机操作系统中,进程状态、优先级和调度是非常重要的概念,它们直接影响着系统的性能、资源利用率和响应速度。理解这些概念不仅对于系统管理员和开发人员来说至关重要,对于任何对计算机系统有兴趣的人都是有益的。

本文将深入探讨进程状态的各种表述方式、影响因素以及在 Linux 内核源代码中的具体实现,以及进程优先级的概念及其在 Linux 中的实现方式。我们还将讨论进程调度和切换的原理,以及 Linux 内核是如何通过各种机制来管理和调度进程,确保系统资源的合理利用和进程之间的公平竞争。

1. 进程状态

1.1. 轻量进程排队这件事情——队列

  • 进程由 task_struct 和可执行程序组成。
  • 进程排队意味着 task_struct 排队,通常是等待某种资源。
  • 一个 task_struct 可以被连接到多种数据结构中,底层队列通常使用链表实现,Linux 中记录偏移量。

1.2. 进程状态的表述及其影响:

  • 状态本质上是 task_struct 中的一个整型变量。
#define New 1
#define Ready 2
#define runing 3
#define running 3
#define block 3
...
  • 状态决定了什么?
    状态决定了进程的后续动作,例如任务的调度。
    Linux中可能会有很多个进程都要根据它的状态执行后续的动作(进程排队了!)
struct runqueue{
	int num;
	task_struct *q;
}	
  • Linux 中的状态包括运行、阻塞、挂起等,由整型变量表示,例如:

运行状态(R):表示进程准备好随时被调度。
阻塞状态(S):表示进程等待软硬件资源,可中断睡眠。
不可中断睡眠(D):表示进程等待硬件资源。
挂起状态(T):暂停进程的执行,让其处于暂停状态,等待其他事件发生。

一个 CPU 一个运行队列, 其中运行状态不仅仅是在CPU上跑,只要是在运行队列里排队的进程都属于运行状态 。
R状态:我以及准备好随时被调度了!

1.3. 挂起状态及处理:

  • 挂起状态在计算机资源紧张时发生。
  • 阻塞挂起状态是进程等待资源时的一种状态。
  • 当进程等待软硬件资源时,如果资源未就绪,进程的 task_struct 可能被置为阻塞状态,并连接到资源提供的等待队列。
  • 状态变迁导致 task_struct 被移动到不同的队列中,以便操作系统进行管理。

1.4.理解 Linux 内核源代码中的状态表述:

为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在Linux内核里,进程有时候也叫做任务)。
下面的状态在kernel源代码里定义:

/*
* 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 */
};
  • Linux 内核中使用数组定义了进程的不同状态,如运行状态(R)、睡眠状态(S)、不可中断睡眠(D)等。
  • 进程状态数组以位图形式表示,可以通过简单的位测试来检测状态组合。
  • 例如,Z(zombie)状态表示进程已经退出,但其状态需要保持,以供上层读取,避免内存泄漏。
  • 为什么要有Z状态? 创建进程是希望这个进程给用户完成工作的,子进程必须得有结果数据,pcb中的。
  • 什么是Z?进程已经退出,但是当进程的状态需要维持住,供上层读取,必须处于Z
  • 如果我父亲不读取呢?僵尸状态,会一直存在。task_struct 对象也一直存在,都是要占内存的。内存泄漏!

在这里插入图片描述

2. 进程优先级

  • 进程优先级是什么?
    前提:进程要访问某种资源,进程进行通过一定的方式(排队),确认享受资源的先后顺序。
  • 为什么?资源过少!(相对的概念)
  • 怎么办?
struct task_struct
{
	// 优先级
	int PRI;
	int nice;
}

在Linux系统中,进程优先级由一个整数表示,范围一般在[60, 99]之间,默认优先级是80。数字越小,优先级越高,进程越有可能先获取系统资源。Linux允许用户调整进程的优先级,但通常不直接修改优先级值(PRI),而是通过调整nice值(nice是进程优先级的修正数据),范围在[-20, 19]之间。负值表示更高的优先级,正值表示更低的优先级。

Linux 为什么要调整优先级是要受限的?

这是因为如果不加限制,有可能出现某些进程将自己的优先级调整得非常高,而其他进程则调整得非常低的情况,从而导致系统资源被不合理地分配。高优先级的进程会优先获取CPU等系统资源,而低优先级的进程可能会长时间无法执行,造成资源饥饿问题。

任何的分时操作系统,在调度上,较为公平的调度。

3. Linux的调度与切换

在 Linux 中,进程调度和切换是操作系统中重要的机制,它们确保了系统资源的合理利用和进程之间的公平竞争。下面是关于进程调度和切换的一些概念:

3.1. 进程调度:

  • 系统中的进程数目通常远远多于可用的 CPU 数目,因此进程之间存在竞争关系。为了高效地完成任务,系统通过进程调度算法来决定何时执行哪个进程。
  • 进程调度算法通常基于进程的优先级、等待时间、历史运行情况等因素来进行决策,以最大程度地提高系统整体的效率和吞吐量。

概念准备:

  1. 进程在运行的时候,放在CPU上,直接必须把进程代码跑完,才行吗?不对。现代操作系统都是,基于时间篇进行轮转的。
  2. 关于竞争性、独立性、并行和并发的概念
  • 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有- 竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级。
  • 独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰。
  • 并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行。
  • 并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发。

3.2. 进程切换(并发):

  • 在多任务操作系统中,多个进程会共享 CPU 资源。当一个进程的时间片用完或者发生阻塞等情况时,操作系统需要切换到另一个进程,以保证系统的响应性和效率。
  • 进程切换涉及保存和恢复进程的上下文信息,包括寄存器状态、内存映射、进程状态等。这些信息被保存在操作系统内部数据结构中,以便在需要时进行切换和恢复。

进程在运行过程中产生的临时数据,以及关于硬件上下文的保存和恢复:

  1. 进程的临时数据:
  • 在执行过程中,进程会产生大量的临时数据,例如变量、函数调用栈等。这些临时数据通常存储在内存中的堆栈段或堆段中,以供程序运行时使用。
  1. 硬件上下文:
  • 当一个进程被调度执行时,CPU 需要保存当前进程的硬件上下文,包括寄存器中的数据、程序计数器(PC)等信息。这些信息构成了进程在 CPU 上运行的环境和状态,称为硬件上下文。
  1. 硬件上下文的保存和恢复:
  • 当进程被调度暂停或切换时,CPU 会将当前进程的硬件上下文保存到内存中,以便稍后恢复。而当该进程再次被调度执行时,CPU 会从内存中恢复之前保存的硬件上下文,使得进程可以从上次执行的位置继续执行。
  1. 区分寄存器和寄存器的内容:
  • CPU 内部的寄存器只有一组,它们用于存储当前正在执行的指令、操作数等关键信息。
  • 寄存器内部保存的数据可以有多套,每个进程都有自己的一套寄存器数据,被称为进程的上下文信息。虽然这些寄存器都是在共享的 CPU 中,但不同进程的寄存器数据是相互隔离的,每个进程都无法直接访问其他进程的寄存器数据。

Linux 实现进程调度和切换的机制主要包括以下几个方面:

  • 使用优先级队列管理进程,以确保高优先级进程优先执行。
  • 考虑进程饥饿问题,避免低优先级进程长时间无法执行的情况发生。
  • 实现时间片轮转调度算法,确保每个进程都有机会执行,并防止某个进程长时间占用 CPU 资源。
  • 使用位图等数据结构记录不同优先级队列的状态,以便高效地选择下一个要执行的进程。
  • 在进程切换时,保存和恢复进程的硬件上下文信息,确保进程能够从切换前的状态无缝地继续执行。 swap(&active, &expried);

总结

本文介绍了进程状态、优先级和调度在计算机操作系统中的重要性和原理。通过对进程状态的各种表述方式和影响因素的讨论,我们了解了进程在操作系统中的不同状态及其意义,以及在 Linux 内核源代码中的具体实现方式。进程优先级的概念及其在 Linux 中的实现方式也得到了阐述,包括通过调整 nice 值来调整进程的优先级。最后,我们深入探讨了进程调度和切换的原理,以及 Linux 内核是如何通过各种机制来管理和调度进程,确保系统资源的合理利用和进程之间的公平竞争。

通过对这些关键概念的理解,我们能够更好地管理和优化系统资源的利用,提高系统的性能和响应速度,从而为用户提供更好的计算机体验。

  • 13
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Q_hd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值