一, 实验环境
win10 -> VMware -> Ubuntu16.04 -> QEMU -> Linux-3.9.4
二, 实验目的
1, 了解在一个极简内核中, 为了实现多进程的切换, 需要哪些必要的数据结构;
2, 了解对于一个 OS 来说, 进程是如何启动以及如何基于时间片轮转对进程进行切换.
三, 实验结果
图 1 实验结果
四, 代码分析
(1) 对应的 PCB(进程控制块)
为了能够实现进程的切换和正常运行, 对于每一个进程, 都需要有一些必要的资源, 参数. 比如, 对应进程的唯一标识 (pid), 进程的状态(state), 每一个进程对应的堆栈(stack), 进程的入口地址(entry), 指向进程队列中位于当前进程的下一进程指针(pnext) 等等.
图 2 PCB 结构体定义
图 3 进程切换的大致流程图
(2)进程切换的逻辑分析
具体来讲, 对于进程的上下文切换, 需要在平常的 C 代码之间嵌入一些必要的汇编代码, 以保存将要被替换的进程的相关信息 (现场) 以及执行下一的进程, 对于新的进程, 也并非是从头开始执行(第一次执行除外), 而是从上一次被中断的地方继续开始执行.
图 4 进程切换中实现进程间上下文切换的汇编代码
(3)极简内核的整体流程分析
图 5 极简内核整体运行流程图
在个人看来, 该极简内核的运行在本质上是一个死循环, 在这个死循环中, 基于固定时间片轮转思想, 修改进程切换标志, 在该死循环中查询进程切换标志, 如果符合要求, 则进行进程的切换, 否则继续执行当前进程, 不进行进程切换. 当然, 这个死循环, 是由内核中的 0 号进程触发. 0 号进程是内核启动起来, 经过相应的初始化之后, 执行的第一个进程.
图 6 my_start_kernel 中对 0 号进程的初始化
.
图 7 my_start_kernel 中对进程链表的初始化(包括 PCB 初始化)
图 8 my_start_kernel 中执行的第一个进程(0 号进程)
图 9 时间片的实现(系统时钟中断
图 10 0 号进程死循环查询是否执行进程切换
四, 总结
通过分析实验代码, 比较清楚地了解一个简单的时间片轮转多道操作系统内核, 了解了操作系统的中断上下文和进程上下文切换. 对于当前执行的进程来说, 如果被分配到的时间片执行完, CPU 则会进行相应的进程切换. 其中的调度程序, 就是在维护一个就绪进程队列, 当进程用完属于它的时间片后, 在队列中就会按照优先级重新排序. 这种调度方式, 应该是属于一种比较简单, 公平同时也是比较高效的方式.
来源: http://www.bubuko.com/infodetail-2985603.html