内容:

(1):从schedule()开始,几种不同类型的进程之间的调度选择;在相同类型的进程之间的调度选择算法

(2):从CPU的IP值的变化上,说明在switch_to宏执行后,执行分析

(3):堆栈发生切换位置,在切换堆栈前后,current_thread_info变化

(4):地址空间发生切换,解释地址空间的切换不会影响后续切换代码的执行

(5):current宏所代表的进程发生变化的源码位置

(6):任务状态段中关于内核堆栈的信息发生变化源码位置

1,从schedule()开始,说明几种不同类型的进程之间的调度选择;在相同类型的进程之间的调度选择算法。

在schedule()函数中,

首先禁止抢占,获取当前CPU,该CPU的执行队列,队列上正在执行的进程,以及该进程的交换计数信息并释放该进程占用的锁。之后,对禁止中断,更新运行队列时钟,该队列的自旋时钟加锁,后清除当前进程的thread_flag中TIF_NEED_RESCHED,

如果进程不在可运行状态,并且可被抢占,若进程处于非阻塞挂起,则将其改为可运行,否则调用deactivate_task()函数,并修改上下文交换次数。其中在deactive_task()函数中调用了denqueue_task()函数:

P进程调用属于自己调度类的dequeue_task()方法,将p从当前rp运行队列上移出。例如对于公平调度队列中的进程调用以下函数:

对p的所有实体除含有子实体的父进程外,从公平队列中移除。

如果运行队列上进程数是0,则先通过idle_balance函数从其他CPU上调度,进行负载均衡。

对当前运行的进程prev,通过调用它所属的类的put_prev_task方法,将当前进程放入运行队列的合适位置。下图展示过程,图为公平调度类的调度方法,之后对实时调度方法的说明(idle类方法为空):

与方法put_prev_entity()方法,将当前进程加入公平调度队列。因为如果该类是公平调度类,则调度一定会在公平调度队列中有一位置,更新当前实例的状态,并入队:

其中入队位置有该值决定entity_key:

对于采用实时调度的类,调用update_curr_rt函数,并置当前进程执行开始时间是0

下图为update_curr_tr函数,

计算delta_exec值为运行队列现在的时钟值与当前进程开始值。更改当前进程的状态,修改当前实时进程的总运行时间与开始时间,对实时调度队列中的实例更新时间。

之后,在运行队列上选择下一个进程中pick_next_task函数。

对于运行队列,如果队列中进程数与公平调度队列中的进程数相同,即没有实时进程时则在公平调度队列中选择进程:

对调度类中具有最高优先级的类赋值给class,调用该类的pick_next_task方法,根据不同调度类又分为:

对于实时进程则:

对于一个实例,如果它不在实时队列组中,则返回拥有这个实例的task_struct结构为next进程并修改执行开始时间为运行队列当时钟前值。

对于公平调度进程则:

返回公平调度队列上选择不在公平调度组中的task_struct。

对于idle,返回队列中的idle task_struct结构,在调度过程中,永远不会返回NULL,因为至少有idle进程的存在。

在队列中从不同类中,选择出了将要被调度的类后,如果选择的进程next与prev不同则,进行进程的上下文切换:

修改交换次数,将next至为当前进程,进行切换。

2,执行完switch_to后,又执行了battier函数,之后又执行finish_task_switch函数

另:

struct task_struct *__switch_to(struct task_struct *prev,struct task_struct *next);

将next->thread.esp中的数据存入esp寄存器中

在switch_to宏执行后,执行ret_from_fork()函数。

执行完这个函数之后,执行include/asm-x86/system.h 下的__switch_to函数()

再执行__unlazy_fpu()函数。

3,堆栈发生切换位置,在切换堆栈前后,current_thread_info变化

对于切换堆栈,在switch_to中查找修改堆栈指针代码即可即:

图中movel %[next_sp],%%esp 即为修改堆栈指针,指向next进程的堆栈。因为在内核态中,栈顶指针减去8K偏移(两页)便可得到thread_info位置,从而,在切换后current_thread_info内容为切换后的新进程的thread_info内容。

4,地址空间发生切换,解释地址空间的切换不会影响后续切换代码的执行

切换地址空间在context_switch函数的switch_mm方法,在switch_mm中,重新加载页表即修改cr3寄存器的值:

切换地址空间发生在切换堆栈之前,不会影响后续代码执行,因为进程的切换发生在内核态,内核态地址空间是共用的。没有修改堆栈指针及其他寄存器的值,即堆栈没有变,栈内值未发生改变。

5,current宏所代表的进程发生变化的源码位置

修改该CPU的current_task为next_p,即current宏发生了改变。

6,任务状态段中关于内核堆栈的信息发生变化源码位置

Tss段在_switch_to中被声明,并被赋值:

其中,esp0即为内核堆栈栈底指针

Linux进程调度和切换过程分析的更多相关文章

  1. Linux进程调度与切换

    2016-04-15 张超<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.分析 进程调度的时机与进程 ...

  2. Linux内核分析:实验八--Linux进程调度与切换

    刘畅 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 概述 这篇文章主要分析Li ...

  3. Linux进程调度(3):进程切换分析

     3.调度函数schedule()分析 当kernel/sched.c:sched_tick()执行完,并且时钟中断返回时,就会调用kernel/sched.c:schedule()完成进程切换.我们 ...

  4. Linux进程调度原理

    Linux进程调度原理 Linux进程调度机制 Linux进程调度的目标 1.高效性:高效意味着在相同的时间下要完成更多的任务.调度程序会被频繁的执行,所以调度程序要尽可能的高效: 2.加强交互性能: ...

  5. Linux进程调度原理【转】

    转自:http://www.cnblogs.com/zhaoyl/archive/2012/09/04/2671156.html Linux进程调度的目标 1.高效性:高效意味着在相同的时间下要完成更 ...

  6. 深度讲解Linux内存管理和Linux进程调度-打通任督二脉

    我在多年的工程生涯中发现很多工程师碰到一个共性的问题:Linux工程师很多,甚至有很多有多年工作经验,但是对一些关键概念的理解非常模糊,比如不理解CPU.内存资源等的真正分布,具体的工作机制,这使得他 ...

  7. [转载]Linux进程调度原理

    [转载]Linux进程调度原理 Linux进程调度原理 Linux进程调度的目标 1.高效性:高效意味着在相同的时间下要完成更多的任务.调度程序会被频繁的执行,所以调度程序要尽可能的高效: 2.加强交 ...

  8. 【原创】(五)Linux进程调度-CFS调度器

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  9. KingbaseES V8R3集群运维案例之---主库系统down failover切换过程分析

    ​ 案例说明: KingbaseES V8R3集群failover时两个cluster都会触发,但只有一个cluster会调用脚本去执行真正的切换流程,另一个有对应的打印,但不会调用脚本,只是走相关的 ...

随机推荐

  1. Oracle之存储过程

    1.存储过程创建 oracle中创建存储过程的语法如下: CREATE [OR REPLACE] PROCEDURE PRO_NAME[(parameter1[,parameter2]...)]is| ...

  2. windows2003服务器不显示桌面怎么办

    ctrl +alt+delete 进入任务管理器应用程序里 创建新任务 C:\WINDOWS\explorer.exe 运行就行

  3. 关于htmlentities 、htmlspecialchars、addslashes的使用

    1.html_entity_decode():把html实体转换为字符. Eg:$str = "just atest & 'learn to use '"; echo ht ...

  4. 怎样在cmd(命令提示符)下进行复制粘贴操作

    如右图,右键命令提示符窗口的标题栏,选择属性.     选择“编辑选项”里的“快速编辑模式”,并确定之:   在弹出的应用选择提示框上选择“保存属性,供以后具有相同标题的窗口使用”:   如此你就可以 ...

  5. String对象中常用的方法

    String对象中常用的方法   1.charCodeAt方法返回一个整数,代表指定位置字符的Unicode编码.strObj.charCodeAt(index)说明:index将被处理字符的从零开始 ...

  6. C#位操作符

    位操作符是对数据按二进制位进行运算的操作符.c#位操作符包括: 按位与 & 按位或 | 按位取反 ~ 左移 << 右移 >> 例如:   6:00000110 3:00 ...

  7. crawler spec

    使用说明 0.写在前面 1.本程序完成的抓取网页并保存其文件的工作. 2.目前的版本还需将工程文件导入eclipse中运行. 3.加载主类MyCrawler生成可执行文件. 4.程序主界面: 1 准备 ...

  8. oracle将两个结果连接后进行查询,得到两个查询的联合结果

    一.需求 用户答题,共3道,必须3题都答完才能提交. 目的:要查询用户答对了几题,答错了几题.(当然此处可以只查答对的题目数,用3减即得答错题的题目数) 二.sql select * ) rightC ...

  9. 2012 Asia Hangzhou Regional Contest

    Friend Chains http://acm.hdu.edu.cn/showproblem.php?pid=4460 图的最远两点距离,任意选个点bfs,如果有不能到的点直接-1.然后对于所有距离 ...

  10. C/C++ 快速排序 quickSort

    下面的动画展示了快速排序算法的工作原理. 快速排序图示:可以图中在每次的比较选取的key元素为序列最后的元素. #include <stdio.h> #include <stdlib ...