2020-2021-1 20209322《Linux内核原理与分析》第九周作业
作业信息
作业课程 | 2020-2021-1Linux内核原理与分析 |
---|---|
作业要求 | 2020-2021-1Linux内核原理与分析第九周作业 |
作业目标 | 进程的切换和系统的一般执行过程 |
作业正文 | 2020-2021-1 20209322《Linux内核原理与分析》第九周作业 |
进程的切换和系统的一般执行过程
一、进程调度的时机
1.1硬中断与软中断
中断是指在计算机执行期间,系统内发生任何非寻常的或非预期的急需处理事件,使得CPU暂时中断当前正在执行的程序而转去执行相应的时间处理程序。待处理完毕后又返回原来被中断处继续执行或调度新的进程执行的过程。引起中断的事件称为中断源。中断源向CPU提出处理的请求称为中断请求。发生中断时被打断程序的暂停点称为断点。CPU暂停现行程序而转为响应中断请求的过程称为中断响应。处理中断源的程序称为中断处理程序。CPU执行有关的中断处理程序称为中断处理。而返回断点的过程称为中断返回。中断的实现由软件和硬件综合完成,硬件部分叫做硬件装置,软件部分称为软件处理程序。
硬中断:由与系统相连的外设(比如网卡、硬盘)自动产生的。主要是用来通知操作系统系统外设状态的变化。比如当网卡收到数据包的时候,就会发出一个中断。我们通常所说的中断指的是硬中断(hardirq)。
软中断:为了满足实时系统的要求,中断处理应该是越快越好。linux为了实现这个特点,当中断发生的时候,硬中断处理那些短时间就可以完成的工作,而将那些处理事件比较长的工作,放到中断之后来完成,也就是软中断(softirq)来完成。
异常:故障(Fault):出现问题,可以恢复到当前指令。退出(Abort):不可恢复的严重故障,导致程序无法继续运行,只能退出。陷阱(Trap):程序主动产生的异常。
1.2进程调度时机
1.2.1 schedule函数
Linux内核通过schedule函数实现进程调度,schedule函数在运行队列中找到一个进程,把CPU分配给它。所以调用schedule函数的时候就是进程调度的时机。
调用schedule函数的两种方法:
1.进程主动调用
2.松散调用
1.2.2上下文
上下文,一般来说,CPU在任何时刻都处于以下3种情况之一:
1运行于用户空间,执行用户进程上下文。
2运行于内核空间,处于进程(一般是内核线程)上下文。
3运行于内核空间,处于中断上下文。
1.2.3进程调度时机
- 用户进程通过特定的系统调用主动让出CPU。
- 中断处理程序在内核返回用户态时进行调度。
- 内核线程主动调用schedule函数让出CPU。
- 中断处理程序主动调用schedule函数让出CPU,涵盖第一和第二种情况。
二、调度策略和算法
调度算法就是从就绪队列中选一个进程。调度策略是为了满足不同的需求,寻找的不同的方法和机制,而调度算法是调度策略的具体实现。
2.1进程分类
按照cpu占用率分
- I/O消耗型进程。需要大量文件或网络读写操作。
- 处理器消耗型进程。视频编码等cpu占用率100%,没有太多硬件进行读写的操作。
按照交互式要求(响应时间)分 - 交互式进程
- 批处理进程
- 实时进程
2.2调度策略
Linux系统中常用的几种调度策略为SCHED_NORMAL、SCHED_FIFO、SCHED_RR。Linux内核进程优先级为0139,数值越高,优先级越低,0为最高优先级。实时进程的优先级取值为099,普通进程只具有nice值,nice值映射到优先级为100139。
2.2.1 SCHED_NORMAL
SCHED_NORMAL是用于普通进程的调度类。
2.6内核版本以后,使用的是CFS调度管理程序。
2.2.2 SCHED_FIFO和SCHED_RR
SCHED_FIFO和SCHED_RR是用于实时进程的调度类,优先级高于SCHED_NORMAL。只有当就绪队列中没有实时进程时,普通进程才能够获得调度。
SCHED_FIFO采用先进先出的策略。SCHED_RR采用更为公平的轮转策略。
2.3CFS调度算法
CFS即为完全公平调度算法,其基本原理是基于权重的动态优先级调度算法。每个进程使用CPU的顺序进程由已使用的CPU虚拟时间(vruntime)决定,已使用的虚拟时间越少,进程排序就越靠前,进程再次被调度执行的概率也就越高。每个进程每次占用CPU后能够执行的时间(ideal_runtime)由进程的权重决定,并且保证在某个时间周期(_sched_period)内运行队列的所以进程都能够至少被调度执行一次。
三、进程上下文切换
3.1进程执行环境切换
为了控制进程的执行,内核必须有能力挂起正在CPU中运行的进程,并恢复执行以前挂起的某个进程。这种行为被称为进程切换,任务切换或进程上下文切换。
进程上下文包含了进程执行需要的所有信息:
- 用户空间地址:包括程序代码、数据、用户堆栈等。
- 控制信息:进程描述符、内核堆栈等。
- 硬件上下文,相关寄存器的值。
最核心的几个关键寄存器:
- CR3:进程页目录表,地址空间,数据。
- ESP:进程内核堆栈,struct thread、进程控制块、内存堆栈存储于连续的8KB区域中,通过ESP获取地址。
- EIP及其他寄存器:进程硬件上下文,即要执行的下条指令及环境。
在实际的代码中,每个进程切换基本由两个步骤组成:
- 切换页全局目录(CR3)以安装一个新的地址空间,这样不同进程的虚拟地址就会经过不同的页表转换为不同的物理地址。
- 切换内核态堆栈和硬件上下文,因为硬件上下文提供了内核执行新进程所需要的所有信息。
四、Linux系统的运行过程
4.1linux系统的一般执行过程
Linux系统的一般执行过程最基本的场景:正在运行的用户态进程X切换到用户态进程Y的过程:
1.正在运行的用户态进程X;
2.发生中断(包括异常,系统调用等),硬件完成以下动作:
- save cs:eip/esp/eflags:当前CPU上下文压入用户态进程X的内核堆栈;
- load cs:eip(entry of a specific ISR) and ss:esp(point to kernel stack)
3.SAVE_ALL,保存现场
4.中断处理过程中或中断返回前调用了schedule(),其中的switch_to做了关键的进程上下文切换;
5.标号1,开始运行用户态进程Y(这里Y曾经通过以上步骤被切换出去过因此可以从标号1继续执行);
6.restore_all,恢复现场;
7.iret-pop cs:eip/ss:esp/eflags,从Y进程的内核堆栈中弹出(2)中硬件完成的压栈内容;
8.继续运行用户态进程Y。
4.2linux系统执行过程中的几种特殊情况
- 通过中断处理过程中的调度时机,内核线程之间相互切换。
- 内核线程主动调用schedule(),只有进程上下文的切换。
- 创建子进程的系统调用在子进程中的执行起点及返回用户态,如fork。
- 加载一个新的可执行程序后返回到用户态的情况,如execve。
五、Linux系统构架与执行过程概览
5.1linux操作系统的构架
5.2ls命令执行过程
六、进程调度相关源代码跟踪和分析
6.1配置运行MenuOS
下载新版本menu
6.2设置断点调试
设置断点
b schedule
b context_switch
b pick_next_task
执行,查看执行情况
七、总结
进程调度是为了合理分配计算机资源,并让每个进程都获得适当的执行机会。由于进程调度函数schedule是内核态函数,且并非系统调用,用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度。
Linux内核调用schedule()函数进行调度,并调用context_switch()进行上下文的切换,pick_next_task()函数封装了进程调度算法。