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

进程调度的时机

  • ntel定义的中断类型
    • 硬中断:CPU的两根引脚(可屏蔽中断和不可屏蔽中断)。若是高电平,则有中断请求。
    • 软中断:包括零错误、系统调用、调试断点等,在CPU执行指令过程中发生的各种特殊情况,也称为异常。异常可以分为3种:故障、退出、陷阱。
  • 进程调度时机
    • linux内核通过schedule函数实现进程调度,schedule函数在运行队列中找到一个进程。把CPU分配给他。每调用一次schedule函数就实现一次进程调度,调用schedule函数就是进程调度的时机。调用schedule函数:
      • 进程主动调用:进程调用阻塞的系统调用等待外设或主动睡眠,最终会在内核中调用到schedule函数。
      • 松散调用:内核代码中可以随时调用schedule函数使当前内核路径让出CPU;也会根据need_resched标记做进程调度,内核检测到need_resched决定是否调用schedule函数。
    • 进程调度时机情况
      • 用户进程通过特定的系统调用主动让出CPU;
      • 中断处理程序在内核返回用户态时进行调度;
      • 内核线程主动调用schedule函数让出CPU;
      • 中断处理程序主动调用schedule函数让出CPU(包括以上两点)。
    • CPU在任何时刻都处于以下3种情况之一:
      • 运行于用户空间,执行用户进程上下文。
      • 运行于内核空间,处于进程上下文。
      • 运行于内核空间,处于中断上下文。

调度策略与算法

  • 基本调度策略
    • 实时进程的调度策略(优先级0~99,静态设定)
      • SCHED_FIFO 先进先出
      • SCHED_RR 轮转策略(时间片)
    • 普通进程的调度类 —— SCHED_NORMAL,只有nice值,映射到优先级为100~139。按优先级占比计算占用CPU的时间。
  • CFS调度算法
    • 调度周期:进程越多,周期越长;上限默认8ms;一个时间周期内队列的所有进程都会至少被调度一次。
__sched_period = nr_running(进程数)*sysctl_sched_min_granularity(默认值)
+ 理论运行时间:每次可获取CPU后最长可占用时间为ideal_runtime.
  ideal_runtime = __sched_period * 进程权重/队列运行总权重
+ 虚拟运行时间:每个进程拥有一个vruntime,每次需要调度时就运行队列中拥有最小的vruntime的进程来运行,最长运行时间为ideal_runtime.
vruntime = 实际运行时间 * NICE_0_LOAD / 进程权重
         = 实际运行时间 * 1024 / 进程权重
NICE_0_LOAD = 1024, 表示nice值为0的进程权重
+ 时钟中断周期:1/CONFIG_HZ秒
+ Linux传统优先级与权重的转化关系是经验值。
+ Linux采用红黑树来存储就绪进程指针,插入时根据vruntime排序,调度时选择最左边的即可。

进程上下文切换

  • 为了控制进程的执行,内核必须有能力挂起正在CPU中运行的进程,并恢复执行以前挂起的进程,这个行为称为进程切换
  • 进程上下文包含了进程执行的所有信息:
    • 用户地址空间:进程代码、数据和用户堆栈等
    • 控制信息:进程描述符、内核堆栈
    • 硬件上下文:存储相关寄存器的值
  • 实际代码中进程切换由两个步骤组成:
    • 切换页全局目录(RC3)以安装一个新的地址空间,这样不同的虚拟地址经过不同的页表转为不同的物理地址。
    • 切换内核态堆栈和硬件上下文

Linux系统的构架

实验

cd LinuxKernel
rm menu -rf
git clone https://github.com/mengning/menu.git
cd menu
ls
make rootfs

cd..
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -S -s

gdb
file linux-3.18.6/vmlinux
target remote:1234
b schedule
b context_switch
b __switch_to
b pick_next_task

配置运行MenuOS系统

配置gdb远程调试和设置断点

使用gdb跟踪分析schedule()函数


执行程序,程序分别停在schedule函数、pick_next_task函数断点、context_switch处,查看代码:

 posted on 2019-11-14 16:24  捞起月亮的渔民  阅读(176)  评论(0编辑  收藏  举报