• 2018-2019-1 20189205 《Linux内核原理与分析》 第九周作业


    进程的切换和系统的一般执行过程

    进程调度的时机

    Linux内核通过schedule函数来实现进程调度。每次调用schedule函数,其都会在进程队列中查找一个进程,将CPU分配给它。
    调用schedule函数的方法

    • 进程主动调用schedule函数,如进程调用阻塞的系统调用等待外设或主动休眠,最终会在内核中调用到schedule函数。
    • 松散调用,内核代码中可以随时调用schedule函数使当前内核路径让出CPU;也会根据need_resched标记做进程调度,内核会检测need_resched决定是否调用schedule函数。

    调用schedule函数的时机
    内核调用schedule函数的时机可以简单归结为如下过程:

    • 用户进程通过特定的系统调用主动让出CPU;
    • 中断处理程序在内核返回用户态时进行调度;
    • 内核线程主动调用schedule函数让出CPU;
    • 中断处理程序主动调用schedule函数让出CPU(包括以上两点)。

    进程调度策略

    考虑算法的整体目标,选择可以满足这个目标所的方法或机制作为对策,即为调度策略。
    Linux系统中常用的调度策略有以下三种:

    • SCHED_FIFO 先进先出的实时进程,如果没有其它更高优先级的可运行实时进程,就可以一直使用cpu运行。对于这种进程,时间片长度是没有意义的。
    • SCHED_RR 时间片轮转的实时进程,所具有相同优先级(且都是当前情况下优先级最高)的SCHED_RR以时间片轮转的方式公平使用cpu。
    • SCHED_NORMAL 时间片轮转的普通进程,时间片用完之后变成过期进程,所有进程都成为过期进程之后,再统一把过期进程转变为活动进程。
      其中前两种为实时进程,优先级取值为099;最后一种为普通进程,只有映射到优先级100139的nice值。

    进程调度算法

    Linux系统的进程调度算法采用CFS即完全公平调度算法,其原理是基于权重的动态优先级调度算法。即:

    • 每个进程使用CPU的顺序由进程已使用的CPU虚拟时间(vrumtime)决定,已使用的虚拟时间越少,进程排序越靠前,进程被在此调度执行的概率越高;
    • 每个进程每次占用CPU后可执行的运行时间(ideal_runtime)由进程的权重决定;
    • 保证每个时间周期(__sched_period)内运行队列中的所有进程都至少被调度一次。

    其中:

    __sched_period = nr_running(进程数)* sysctl_sched_min_granularity(默认值为0.75ms);
    ideal_runtime = __sched_period * 进程权重 / 运行队列总权重 ;
    vrumtime += delta_exec(本次CPU占用时间)* NICE_0_lOAD (nice值为0的进程的权重) / se->load.weight (自身权重);
    

    进程上下文

    进程上下文包含了进程执行需要的所有信息:

    • 用户地址空间:包括程序代码,数据,用户堆栈等;
    • 控制信息:进程描述符,内核堆栈等;
    • 硬件上下文:相关寄存器的值。
      进程切换就是变更进程上下文。

    代码跟踪分析

    配置断点:

    schedule()函数上下文

    pick_next_task函数上下文

    context_switch函数上下文

    问题分析

    对于书中有关vruntime的部分:

    在进行计算时,书中的代码存在一些问题。

    • 第一行的判断条件应当是if se->load.weight == NICE_0_LOAD 因为 if 部分计算的是nice值为0的进程的 vruntime值,因此判断条件应为==,而非!=
    • 最后一行else部分的代码应当是vrumtime+= delta_exec *NICE_0_lOAD/se->load.weight

    另外在之后的论述中:

    • 虚拟时间等于实际执行的物理时间的进程不应当是0优先级的进程,而是nice值为0的进程。
    • 检查是否需要设置的调度标志是need_resched而非need_schedule
  • 相关阅读:
    Vector3函数理解-计算两向量之间的角度
    Android报错Type Error executing aapt: Return code -1
    android中 onResume()方法什么时候执行 ??(转)
    自行实现Kinect 手势Demo踩的坑
    Kinect 2.0 默认姿势的中文意思
    C#限制float有两位小数
    Android View 从左边滑出动画 ,以及从左上,左下,右上,右下放大动画。
    注册谷歌账户时最后一步验证账户输入手机号说此电话号码无法用于进行验证,如何解决?
    Mac使用sonarqube进行代码检测
    Unable to find method 'org.gradle.api.tasks.TaskInputs.file
  • 原文地址:https://www.cnblogs.com/hzj20189205/p/10093116.html
Copyright © 2020-2023  润新知