zoukankan      html  css  js  c++  java
  • 2020-2021-1 20209316《Linux内核原理与分析》第九周作业

    2020-2021-1 20209316《Linux内核原理与分析》第九周作业

    《Linux内核原理与分析》第九周作业

    这个作业属于哪个课程 <2020-2021-1Linux内核原理与分析)>
    这个作业要求在哪里 <2020-2021-1Linux内核原理与分析第九周作业>
    这个作业的目标 <理解进程调度时机跟踪分析进程调度与进程切换的过程>
    作业正文 https://www.cnblogs.com/camusxd/p/14092931.html

    一、实验八:进程调度相关源代码跟踪和分析

    1、重新克隆一个menu,然后编译内核

    2、打开调试模式,另打开一个窗口进行gdb调试,并设置断点

    3、使用gdb跟踪分析schedule()函数,按c执行,停在schedule函数断点处。

    4、pick_next_task断点处某种调度策略和调度算法选择了下一个进程来切换,context_switch断点处用来实现进程的切换。

    二、知识学习
    1.阐释linux操作系统的整体构架

    首先,Linux系统包含一个内核,内核,实质是一个软件,特殊的地方在于,内核具备直接操纵CPU资源,内存资源,I/O资源等的能力。
    内核之外是系统调用。系统调用这层,相当于内核增加了一层封装。将内核操作的复杂性封装起来,对外层提供透明的调用。系统调用可以理解为操作系统的最小功能单位,所有有应用程序,都是将通过将系统调用组合而成的。
    系统调用之外,就是应用程序,各种各样的应用程序。特殊的有两个,一个是Shell,它是一个特殊的应用程序,俗称命令行。类似于windows的cmd,是一个命令解释器。有些应用程序是基于Shell做的,而不是基于系统调用。另一个特殊的是公用函数库。系统调用是操作系统的最小功能单位,一个Linux系统,根据版本不同,大约包含240~260个系统调用。为了使得操作更为简单,更加便于应用程序使用,Linux系统对系统调用的部分功能进行了再次封装,形成了公用函数库,以供应用程序调用。公用函数库中的一个方法,实质是若干个系统调用以特定的逻辑组合而成。

    2.理解linux系统的一般执行过程和进程调度的时机
    2.1 Linux系统的一般执行过程分析
    最一般的情况:

    • 正在运行的用户态进程X切换到运行用户态进程Y的过程
    • 正在运行的用户态进程X
    • 发生中断——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).
    • SAVE_ALL //保存现场
    • 中断处理过程中或中断返回前调用了schedule(),其中的switch_to做了关键的进程上下文切换
    • 标号1之后开始运行用户态进程Y(这里Y曾经通过以上步骤被切换出去过因此可以从标号1继续执行)
    • restore_all //恢复现场
    • iret - pop cs:eip/ss:esp/eflags from kernel stack
    • 继续运行用户态进程Y
      2.2 Linux系统执行过程中的几个特殊情况
      通过中断处理过程中的调度时机,用户态进程与内核线程之间互相切换和内核线程之间互相切换,与最一般的情况非常类似,只是内核线程运行过程中发生中断没有进程用户态和内核态的转换;内核线程主动调用schedule(),只有进程上下文的切换,没有发生中断上下文的切换,与最一般的情况略简略;创建子进程的系统调用在子进程中的执行起点及返回用户态,如fork; 加载一个新的可执行程序后返回到用户态的情况,如execve;
      2.3 内核与舞女
    • 3G仅内核态可以访问
      2.4 进程调度的时机
      linux内核通过schedule函数实现进程调度,schedule函数在运行队列中找到一个进程,把CPU分配给它。调用schedule函数一次就是调度一次。调用schedule函数的时候就是进程调度的时机。
      调用schedule函数有两种方法:
    • 进程主动调用schedule()
    • 松散调用
      进程调度时机如下:
    • 用户进程通过特定的系统调用主动让出CPU
    • 中断处理程序在内核返回用户态时进行调度
    • 内核线程主动调用schedule函数让出CPU
    • 中断处理程序主动调用schedule函数让出CPU,涵盖第一和第二种情况
    • Linux内核中没有操作系统中定义的线程概念,从内核角度看,不管是进程还是内核线程都对应一个task_struct数据结构,本质上都是进程,linux系统在用户态实现的线程库pthread是通过在内核中多个进程共享一个地址空间实现的。
      一般来说,cpu在任何时刻都处于以下3种情况之一:
    • 运行于用户空间,执行用户进程上下文
    • 运行于内核空间,处于进程(一般是内核线程)上下文
    • 运行于内核空间,处于中断上下文。
      内核线程以进程上下文的形式运行在内核空间中,本质上还是进程,但是它还有调用内核代码的权限,比如主动调用schedule函数让出cpu等

    三、反思总结
    进程提供了两种优先级,一种是普通的进程优先级,第二个是实时优先级。前者适用SCHED_NORMAL调度策略,后者可选SCHED_FIFO或SCHED_RR调度策略。任何时候,实时进程的优先级都高于普通进程,实时进程只会被更高级的实时进程抢占,同级实时进程之间是按照FIFO(一次机会做完)或者RR(多次轮转)规则调度的。

      首先,说下实时进程的调度

      实时进程,只有静态优先级,因为内核不会再根据休眠等因素对其静态优先级做调整,其范围在0MAX_RT_PRIO-1间。默认MAX_RT_PRIO配置为100,也即,默认的实时优先级范围是099。而nice值,影响的是优先级在MAX_RT_PRIO~MAX_RT_PRIO+40范围内的进程。

      不同与普通进程,系统调度时,实时优先级高的进程总是先于优先级低的进程执行。知道实时优先级高的实时进程无法执行。实时进程总是被认为处于活动状态。如果有数个 优先级相同的实时进程,那么系统就会按照进程出现在队列上的顺序选择进程。假设当前CPU运行的实时进程A的优先级为a,而此时有个优先级为b的实时进程B进入可运行状态,那么只要b<a,系统将中断A的执行,而优先执行B,直到B无法执行(无论A,B为何种实时进程)。

      不同调度策略的实时进程只有在相同优先级时才有可比性:

      1. 对于FIFO的进程,意味着只有当前进程执行完毕才会轮到其他进程执行。由此可见相当霸道。

      2. 对于RR的进程。一旦时间片消耗完毕,则会将该进程置于队列的末尾,然后运行其他相同优先级的进程,如果没有其他相同优先级的进程,则该进程会继续执行。

      总而言之,对于实时进程,高优先级的进程就是大爷。它执行到没法执行了,才轮到低优先级的进程执行。等级制度相当森严啊。

  • 相关阅读:
    DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践
    UVA10071 Back to High School Physics
    UVA10071 Back to High School Physics
    UVA10055 Hashmat the Brave Warrior
    UVA10055 Hashmat the Brave Warrior
    UVA458 The Decoder
    UVA458 The Decoder
    HDU2054 A == B ?
    HDU2054 A == B ?
    POJ3414 Pots
  • 原文地址:https://www.cnblogs.com/camusxd/p/14092931.html
Copyright © 2011-2022 走看看