zoukankan      html  css  js  c++  java
  • linux内核分析第八周理解进程调度时机跟踪分析进程调度与进程切换的过程

    实验原理:
    一、调度时机
    不同类型的进程有不同的调度需求
    第一种分类: 
          I/O-bound 
               频繁的进行I/O
               通常会花费很多时间等待I/O操作的完成
         CPU-bound 
               计算密集型
               需要大量的CPU时间进行运算
    第二种分类 
        批处理进程(batch process) 
               不必与用户交互,通常在后台运行
               不必很快响应
               典型的批处理程序:编译程序、科学计算
        实时进程(real-time process) 
               有实时需求,不应被低优先级的进程阻塞
               响应时间要短、要稳定
               典型的实时进程:视频/音频、机械控制等
        交互式进程(interactive process) 
               需要经常与用户交互,因此要花很多时间等待用户输入操作
               响应时间要快,平均延迟要低于50~150ms
              典型的交互式程序:shell、文本编辑程序、图形应用程序等
    二、进程调度的时机
    中断处理过程(包括时钟中断、I/O中断、系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule(); 
    用户态进程只能被动调度。
    内核线程可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度;
    内核线程是只有内核态没有用户态的特殊进程。内核线程可以主动调度,也可以被动调度。
    用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度。
    schedule()函数选择一个新的进程来运行,并调用context_switch进行上下文的切换,这个宏调用switch_to来进行关键上下文切换
        next = pick_next_task(rq, prev);//进程调度算法都封装这个函数内部
         context_switch(rq, prev, next);//进程上下文切换
         switch_to利用了prev和next两个参数:prev指向当前进程,next指向被调度的进程
    三、linux进程调度与进程切换
    内容:
    (1)从schedule()开始,几种不同类型的进程之间的调度选择;在相同类型的进程之间的调度选择算法
    首先禁止抢占,获取当前CPU,该CPU的执行队列,队列上正在执行的进程,以及该进程的交换计数信息并释放该进程占用
    的锁。
    之后,对禁止中断,更新运行队列时钟,该队列的自旋时钟加锁,后清除当前进程的thread_flag中TIF_NEED_RESCHED。
    如果进程不在可运行状态,并且可被抢占,若进程处于非阻塞挂起,则将其改为可运行,否则调用deactivate_task()函数,并修改上下文交换次数。其中在deactive_task()函数中调用了denqueue_task()函数:
    (2)从CPU的IP值的变化上,说明在switch_to宏执行后,执行分析
    (3)堆栈发生切换位置,在切换堆栈前后,current_thread_info变化
    保存当前进程的flags ;将当前堆栈的基址压栈;保存当前的栈顶;内核堆栈的切换;保存当前进程的eip
    (4)地址空间发生切换,解释地址空间的切换不会影响后续切换代码的执行
    (5)current宏所代表的进程发生变化的源码位置
    (6)任务状态段中关于内核堆栈的信息发生变化源码位置
    实验过程:
    同上周实验一样,先把Menu删掉在clone一个
     
    单步调试
    设置断点
    实验总结:
    通过学习,我们了解到Linux使用了堆栈进行了进程调度。schedule()在需要的时候重新获得大内核锁、重新启用内核抢占、并检查是否一些其他的进程已经设置了当前进程的tlf_need_resched标志,如果是,整个schedule()函数重新开始执行,否则,函数结束。linux调度的核心函数为schedule,schedule函数封装了内核调度的框架。细节实现上调用具体的调度类中的函数实现。当切换进程已经选好后,就开始用户虚拟空间的处理,然后就是进程的切换switch_to()。所谓进程的切换主要就是堆栈的切换,这是由宏操作switch_to()完成的。
  • 相关阅读:
    [转]linux top 命令
    [转]Linux下实用的查看内存和多核CPU状态命令
    Totem ring protocal
    qemu qemusystemx86_64 qemukvm kvm 四个命令
    jsp>过滤器 小强斋
    jsp>Tomcat 6.0数据源配置记录 小强斋
    jsp>过滤器 小强斋
    jsp>监听器 小强斋
    jsp>Tomcat 6.0数据源配置记录 小强斋
    jsp>jsp执行过程 小强斋
  • 原文地址:https://www.cnblogs.com/baka/p/5386941.html
Copyright © 2011-2022 走看看