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的进程。一旦时间片消耗完毕,则会将该进程置于队列的末尾,然后运行其他相同优先级的进程,如果没有其他相同优先级的进程,则该进程会继续执行。

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

posted @ 2020-12-06 15:39  20209316滕源  阅读(115)  评论(0编辑  收藏  举报