目录
优先级
概念
为什么优先级要限制在一定范围内
进程切换
方式
EIP寄存器(程序计数器)
进程在运行时会使用寄存器来保存临时数据
进程的上下文是什么?
进程的上下文保存到哪?
内核栈或专门的上下文结构也在内核空间?那为什么不直接放在task_struct里?
内核栈拓展
Linux2.6.11下进程的调度队列
运行队列
调度队列概念
字段
prio_array结构
调度的做法
问为什么要两个prio_array?
重点
优先级
概念
- 进程在竞争系统资源时的执行顺序
- 优先级的范围60-99,默认为80;这里60最大
- 进程PCB中存在nice值,通过修改nice值来修改优先级
- PRI = pri + NI;pri为确定的起点即80;加减nice值得到最终值
- 改nice值:top;r;pid;nice 不能用小键盘,Backspace也不可以;这通常是因为
top
命令的输入模式或终端设置的问题
为什么优先级要限制在一定范围内
- 较为均衡的让每一个进程都要得到调度,不然容易导致优先级较低的进程无法得到CPU资源,出现进程饥饿
- 补充:这种限制能够帮助操作系统更好地管理资源分配,使所有进程都有机会得到调度,进而确保系统的整体性能和响应性。
进程切换
方式
- 在 Linux 中,进程的调度和切换主要是基于 时间片轮转 和 抢占式调度 的组合方式
EIP寄存器(程序计数器)
- 保存着当前进程正在执行的指令的地址;当进程切换时,操作系统会保存当前进程的 EIP 值,这样当该进程再次获得 CPU 资源时,可以从正确的位置继续执行
进程在运行时会使用寄存器来保存临时数据
- CPU 寄存器用于存放临时数据、操作数、地址以及其他关键信息
- 每个进程都有其自己的寄存器内容,寄存器中存储的数据对不同的进程来说是不同的
进程的上下文是什么?
- 上下文 是指进程在 CPU 上执行时的所有状态信息,这包括程序计数器(EIP)、通用寄存器、标志寄存器、状态寄存器、栈指针以及其它状态信息
进程的上下文保存到哪?
- 老系统会将当前进程的上下文保存到PCB
- 现代操作系统,特别是在 Linux 中,由于内核的演变和复杂性增加,PCB 结构变得越来越大进程的上下文并不总是直接保存在 PCB,而是在保存到其内核栈或专门的上下文结构,并通过 PCB 中的指针引用这些信息
内核栈或专门的上下文结构也在内核空间?那为什么不直接放在task_struct里?
- 一个较小的
task_struct
更容易管理,尤其是在频繁的进程调度和上下文切换中,减少task_struct
的大小,使得调度器在进行进程切换时能够更快地访问和操作这些数据 - 灵活性和扩展性
内核栈拓展
- 作用:内核栈是每个进程在内核态时使用的一块内存区域(位于内核空间),通常用于存储函数调用的返回地址、局部变量、函数参数以及进程在进入内核态时的上下文信息(如寄存器的内容)
- 每个进程在进入内核态时都会使用自己独立的内核栈(例如 8 KB 或 16 KB),以确保足够的空间存储局部变量和上下文信息
- 使用自己独立的内核栈用于与CPU寄存器内容和内核栈内容的“切换”(赋值操作)
Linux2.6.11下进程的调度队列
这是一个调度器使用的运行队列的数据结构
运行队列
- 是一种特定的调度队列,专门用于管理和调度那些已经准备好运行的进程
调度队列概念
- 调度队列是一个泛指的概念,用来描述系统中所有等待被调度的进程的集合,它涵盖了操作系统中用于管理不同状态和不同需求的各种队列
- 就绪队列
- 等待队列
- 阻塞队列
字段
- active:
active
是一个指针,它指向prio_array
结构;prio_array
结构中包含了实际的队列数据(即不同优先级的进程链表)包含所有当前正在运行或准备运行的进程。这些进程有剩余的时间片,且调度器会优先从这个队列中选择进程进行调度 - expired:包含那些已经用完时间片的进程。进程在用完分配的时间片后会被移动到
expired
队列中,等待下一轮调度周期
prio_array结构
- nr_active:当前活跃的进程数量(一共有多少个进程)
- bitmap[5]:用于标识哪些优先级队列非空的位图(32 * 5 个0,用其中的0-139位来表示queue指针数组中下标对应的元素是否为空)
- queue:这是一个链表数组,包含了所有不同优先级的进程队列
调度的做法
- 新的进程链入expired的进程链表中
- 通过swap(avtive, expired)即可交换
问为什么要两个prio_array?
- 防止一直插入优先级高的进程,导致优先级低的进程一直得不到调度出现进程饥饿
重点
- 优先级概念,怎么修改,作用
- 进程切换中,EIP寄存器,上下文,内核栈是需要 理解记忆 的
- Linux2.6.11的调度队列,可以当做自己对进程调度时运行队列的理解逻辑