感觉像是绕了一圈,又回到了起点,终究还是逃不过对这一块的挖掘。
进程的几种不同分类:第一种分类:类型一:I/O-bound:频繁的进行I/O,通常会花费很多的时间等待I/O操作的完成;类型二:CPU-bound:计算密集型 ,需要大量的CPU时间进行运算第二种分类:类型一:批处理进程 ;类型二:实时进程;类型三:交互式进程。
调度策略:是一组规则,它们决定什么时候以怎样的方式选择一个新的进程运行,Linux的调度基于分时和优先级:随着版本的变化,分时技术在不断变化,Linux既支持普通的分时进程,也支持实时进程,Linux中的调度是多种调度策略和调度算法的混合。
进程调度的时机:
- 中断处理过程中,直接调用schedule()
- 内核线程可以直接调用schedule()进行进程切换
系统调用的过程,我们依然使用GDB来跟踪,如下:
- 找到了进程调度的时机
- 进行上下文切换的宏
- 具体的细节实现
- 采取相应的调度算法来找到下一个要执行的任务
- 进行任务的状态指示的改变
- 真正的任务上下文切换
- 这不,从kernel返回了。
总结下来,一般过程如下:
我们可以有了一个条件来理解linux系统的一般运行状态,其中有一个用户态进程X需要切换到用户进程Y。从正在运行的用户态进程X切换到正在运行的用户态进程Y的过程
1.正在运行的用户态进程X
2.发生中断——save cs:eip/esp/eflags(current)to kernel stack,then 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:eip/eflags from kernel stack
8.继续运行用户态进程Y