Linux内核分析之理解进程调度时机跟踪分析进程调度与进程切换的过程
一、原理分析
1.调度时机 背景
不同类型的进程有不同的调度需求
第一种分类
I/O-bond:频繁的进行I/O;通常会花费很多时间等待I/O操作的完成
CPU-bound:计算密集型;需要大量的CPU时间进行运算
第二种分
批处理进程(batch process):不必与用户交互,通常在后台运行;不必很快响应。典型的批处理程序:编译程序、科学计算
实时进程(real-time process):有实时需求,不应被低优先级的进程阻塞;响应时间要短、要稳定。典型的实时进程:视频/音频、机械控制等
交互式进程(interactive process):需要经常与用户交互,因此要花很多时间等待用户输入操作;响应时间要快,平均延迟要低于50~150ms。典型的交互式程序:shell、文本编辑程序、图形应用程序等
2.Linux中的进程调度
Linux既支持普通的分时进程,也支持实时进,Linux中的调度是多种调度策略和调度算法的混合。
调度策略是一组规则,它们决定什么时候以怎样的方式选择一个新进程运行
Linux的调度基于分时和优先级Linux的进程根据优先级排队,根据特定的算法计算出进程的优先级,用一个值表示,这个值表示把进程如何适当的分配给CPU。
Linux中进程的优先级是动态的,调度程序会根据进程的行为周期性的调整进程的优先
较长时间未分配到CPU的进程,通常↑
已经在CPU上运行了较长时间的进程,通常↓
3.scheudle 函数◦schedule函数实现调度
目的:在运行队列中找到一个进程,把CPU分配给它
调用方法:
直接调用,如sleep_on
松散调用,根据need_resched标记
4.进程调度的时机
中断处理过程(包括时钟中断、I/O中断、系统调用和异常)中,直接调用schedule(),或者返回用户态时根据 need_resched 标记调用schedule()。
内核线程可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度。
用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度。
用户态被动调度
内核线程只有内核态没有用户态的特殊进程,无需系统调用。
5.进程的切换
为了控制进程的执行,内核必须有能力挂起正在CPU上执行的进程,并恢复以前挂起的某个进程的执行,这叫做进程切换、任务切换、上下文切换;
挂起正在CPU上执行的进程,与中断时保存现场是不同的,中断前后是在同一个进程上下文中,只是由用户态转向内核态执行。
进程上下文包含了进程执行需要的所有信息:用户地址空间: 包括程序代码,数据,用户堆栈等;控制信息 :进程描述符,内核堆栈等;硬件上下文(注意中断也要保存硬件上下文只是保存的方法不同)
schedule()函数选择一个新的进程来运行,并调用context_switch进行上下文的切换,这个宏调用switch_to来进行关键上下文切换
next = pick_next_task(rq, prev);//进程调度算法都封装这个函数内部
context_switch(rq, prev, next);//进程上下文切换
switch_to利用了prev和next两个参数:prev指向当前进程,next指向被调度的进程
6.进程代码切换代码分析
esp 先切,eip 再切换利用push eip +call 起到了类似的call 作用,但是灵活修改了eip 。
7.Linux系统的一般执行过程
最一般的情况:正在运行的用户态进程X切换到运行用户态进程Y的过程
在运行的用户态进程X 发生中断,硬件完成以下:
save cs:eip/esp/eflags(current) to kernel stack
load cs:eip(entry of a specific ISR) and ss:esp(point to kernel stack).
SAVE_ALL //保存现场
中断处理过程中或中断返回前调用了schedule(),其中的switch_to做了关键的进程上下文切换
标号1之后开始运行用户态进程Y(这里Y曾经通过以上步骤被切换出去过因此可以从标号1继续执行
已经变成Y进程上下文,真是 庄周做梦
restore_all //恢复现场
iret - pop cs:eip/ss:esp/eflags from kernel stack
继续运行用户态进程Y
二、实验内容
在shell中依次运行以下命令,获取本次实验的代码,并编译运行
cd LinuxKernel
rm menu -rf
git clone https://github.com/mengning/menu.git
cd menu
mv test_exec.c test.c
make rootfs
效果如下:
关闭QEMU窗口,在shell窗口中,cd LinuxKernel回退到LinuxKernel目录,使用下面的命令启动内核并在CPU运行代码前停下以便调试:
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
接下来,我们就可以水平分割一个新的shell窗口出来,依次使用下面的命令启动gdb调试
gdb (gdb) file linux-3.18./vmlinux (gdb) target remote:
并在内核函数schedule的入口处设置断点,接下来输入c继续执行,则系统即可停在该函数处,接下来我们就可以使用命令n或者s逐步跟踪,可以详细浏览pick_next_task,switch_to等函数的执行过程
三、总结
经过这一阶段的学习,我对Linux内核有了一些初步的认识。和Windows相比,Linux使用命令较多,这是让我感觉比较困难的一点。而且由于之前未学过操作系统,因此对于一些基础概念的理解也不够,经常听着听着就晕了,得结合网上的资料再反复看课程才能勉强理解一二。
但是,我觉得自学是大学的特色(虽然我高中就开始自学),因此,我在此期间还学习了另一本书——《Linux内核设计的艺术》,这本书的特点是图比较多,不是完全靠文字和代码讲解,对于我这种喜欢看漫画的人非常合适。而且讲解得深入浅出,适合没有基础从头学起。我想,既然学不会跑,那我就从走学起。这本讲解Linux内核的书链接为http://pan.baidu.com/s/1kTFXkTh,祝大家都能学懂Linux内核设计的精妙。
刘帅
原创作品转载请注明出《Linux内核分析》
MOOC课程http://mooc.study.163.com/course/USTC-1000029000
Linux内核分析之理解进程调度时机跟踪分析进程调度与进程切换的过程的更多相关文章
- 理解进程调度时机跟踪分析进程调度与进程切换的过程(Linux)
----------------------------------------------------------------------------------- 理解进程调度时机跟踪分析进程调度 ...
- 20135202闫佳歆--week 8 实验:理解进程调度时机跟踪分析进程调度与进程切换的过程--实验及总结
week 8 实验:理解进程调度时机跟踪分析进程调度与进程切换的过程 1.环境搭建: rm menu -rf git clone https://github.com/megnning/menu.gi ...
- Linux内核设计第八周学习总结 理解进程调度时机跟踪分析进程调度与进程切换的过程
陈巧然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.视频内容 Linux ...
- Linux内核分析——理解进程调度时机跟踪分析进程调度与进程切换的过程
20135125陈智威 +原创作品转载请注明出处 +<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验 ...
- Linux内核分析实验八------理解进程调度时机跟踪分析进程调度与
一.进程调度与进程调度的时机分析 1.不同类型的进程有不同的调度需求 Linux既支持普通的分时进程,也支持实时进程. Linux中的调度是多种调度策略和调度算法的混合. 2.调度策略:是一组规则,它 ...
- linux内核分析第八周-理解进程调度时机跟踪分析进程调度与进程切换的过程
实验原理: 一.调度时机 不同类型的进程有不同的调度需求 第一种分类: I/O-bound 频繁的进行I/O 通常会花费很多时间等待I/O操 ...
- linux内核分析作业8:理解进程调度时机跟踪分析进程调度与进程切换的过程
1. 实验目的 选择一个系统调用(13号系统调用time除外),系统调用列表,使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用 分析汇编代码调用系统调用的工作过程,特别是参数的传递的方 ...
- linux内核分析 第八周 理解进程调度时机跟踪分析进程调度与进程切换的过程
笔记: 实验:使用gdb跟踪分析一个schedule()函数
- Linux内核分析--理解进程调度时机、跟踪分析进程调度和进程切换的过程
ID:fuchen1994 姓名:江军 作业要求: 理解Linux系统中进程调度的时机,可以在内核代码中搜索schedule()函数,看都是哪里调用了schedule(),判断我们课程内容中的总结是否 ...
随机推荐
- sql server 查询和Kill死锁进程
查询死锁进程语句 select request_session_id spid, OBJECT_NAME(resource_associated_entity_id) tab ...
- C#字符串操作(參照圓友)
直接上實例代碼 staticvoid Main(string[] args) { string s =""; //(1)字符访问(下标访问s[i]) s ="ABCD&q ...
- sql server 分页存储过程
----------------------分页存储过程------------------------------------------------------------------------ ...
- pod导入融云路径报错解决办法
build Settings中搜索sear Search Patchs下点开Library Search Paths 将$(inherited)"$(SRCROOT)/Pods"分 ...
- python学习之——django环境搭建
Django是一个基于MVC构造的框架,用于web开发,主要目的是简便.快速的开发数据库驱动的网站. 前提:已经安装python 搭建步骤: 1.https://www.djangoproject.c ...
- 【转】oracle 监听静态注册举例解析
网上有很多关于oracle 监听静态注册的文章,但大多都是简单说说,并没有详细的例子,这里,将结合linux as3 下的oracle 10gR2.0.1 举一个具体的例子 1.在 $ORACLE_H ...
- 实用的PHP功能详解(一)_php glob()用法
一.使用glob()查找文件 大部分PHP函数的函数名从字面上都可以理解其用途,但是当你看到 glob() 的时候,你也许并不知道这是用来做什么的,其实glob()和scandir() 一样,可以用来 ...
- 搭建高可用mongodb集群(三)—— 深入副本集内部机制
在上一篇文章<搭建高可用mongodb集群(二)—— 副本集> 介绍了副本集的配置,这篇文章深入研究一下副本集的内部机制.还是带着副本集的问题来看吧! 副本集故障转移,主节点是如何选举的? ...
- spring aop实现
Spring 有如下两种选择来定义切入点和增强处理. 基于 Annotation 的"零配置"方式:使用@Aspect.@Pointcut等 Annotation 来标注切入点和增 ...
- 《笨办法学C》笔记之指针
C语言编程主要操作的对象就是指针. 指针从哪里来 指针就是表示内存存储区域的一组数值,使用%p格式化字符串. Linux系统会为程序维护两个临时变量存储位置:栈.堆.栈的空间少,栈通常在用户更高的地址 ...