身上
8.1硬件中断与软中断
中断:通常被定义成一个事件,该事件改变处理器执行的指令顺序。这样的事件与cpu芯片外部电路产生
的电信号相对应。
中断的产生:每个能够发出中断请求的硬件设备控制器都有一条称为IRQ的输出线(中断线)。所有的IRQ线都与一个中断控制器的输入引脚相连,中断控制器与cpu的intr引脚相连。
中断向量:每个中断由0-255之间的一个8位数来标识。称为中断向量。
中断描述符表:IDT是一个系统表,它与每一个中断或者异常向量相联系,每一个向量在表中有相应的中断处理程 序的入口地址。cpu的idtr寄存器执行IDT表的物理基地址。
中断的硬件处理:在内核被init进程初始化后,cpu运行在保护模式下。当执行一条指令后,sc和eip这对寄存器包 含了下一条将要执行的指令的逻辑地址。在执行这条指令之前,cpu控制单元会检查在运行前一条指令时是 否发生了一个中断。如果发生了,cpu控制单元处理中断。
每个进程都有两个栈:用户栈和内核栈。检查信号中断时在内核态即将进入用户态的时候,而不是任何时候都检查的。
8.1.1 硬件中断
硬中断是外部设备对cpu的中断。
可以用下面的流程来表示: 中断产生源 --> 中断向量表 (idt) --> 中断入口 ( 一般简单处理后调用相应的函数) --->do_IRQ--> 后续处理(软中断等工作)
段选择符和偏移量决定了中断处理函数的入口地址(中断入口),如下图。
8.1.2 软中断
软中断是软件实现的中断,也就是程序运行时其他程序对它的中断。软中断是利用硬件中断的概念,用软件方式进行模拟,实现宏观上的异步执行效果。
软中断通常是硬中断服务程序对内核的中断。软中断的工作过程模拟了硬中断过程,当某一个软中断事件发生后,首先需要设置对应的中断标记位,触发中断事务,然后唤醒守护进程去检查中断状态寄存器,如果查询软中断状态寄存器irq_stat发现某一个软中断事务发生,那么通过软中断向量表调用软中断服务程序action。
8.3调度算法
调度算法就是从就绪队列中选一个进程。一般来说他需要综合考虑以下因素:
8.3.1 调度策略
Linux即作为服务器使用,又作为桌面PC使用,同时还是是主要的嵌入式设备操作系统,以满足不同的调度需求。
服务器的典型调度需求:
xxxx
xxxx
xxxx
桌面系统的典型调度需求:
xxxx
xxxx
xxxx
嵌入工实时控制系统的典型调度需求:
xxxx
xxxx
xxxx
Linux支持三种基本的调度策略,以满足不同进程的调度需求。这相当于是按照进程的调度方式对进程进行分类。
三种具体的策略如下:
xxx
xxx
xxx
8.3.2 CFS调度算法
CFS即为完全公平调度算法,其基本原理基于权重的动态优先级调度算法。每个进程在启动时会根据其优先级计算“理论运行时间”(CPU的欠债),然后每次运行都统计其“实际支行时间”(CPU的还款),调度算法就是选两者差值最大者。调度器每次都选“CPU欠的最多的”那个进程。
先用一个极端简化的例子来说明其原理: 假定CPU的总运行时间为60分钟,每15分钟调度一次。
| 进程 | 权重 | 理论运行时间 | | ------ |:----- 😐 -----: | | A | 1 | 10 分钟 | | B | 2 | 20 分钟 | | C | 3 | 30 分钟 |
首次调度时,CPU欠C30分钟,最多,所以C被调度到执行了15分钟,相当于CPU还了C15分钟,就只欠C15分钟了;第二次调度时,就变成欠B最多了,20;B运行15分钟后,欠B5分钟,又变成欠C最多了;C再运行15分钟后,欠A最多了;然后A,然后B。调度结束。
其具体涉及相关代码主要有以下:
Linux传统优先级与权重的转换关系
理论运行时间的估算
实际运行时间(vruntime)的估算优化
计算结果的排序与存储(rbtree)