Jan’s simulative OS
Author: 黄海涛(JanLen Huang)
Operating System Design 课程实验
这次开始写一个模拟的OS,可以模拟作业的高级调度,和进程的低级调度,以及用银行家算法实现资源的分配,以及内存的分配等,编译程序还没完善。
源码链接: https://github.com/JinLin541/JanOS_1.1
1.基于JVM的模拟OS
我希望我的os是一个完整的OS,也就是说可以真正得实现进程的生命周期,资源的分配,以及 内存的分配,而不是一个验证算法的程序。使用JVM来模拟处理机,可以用线程来模拟进程,用并发编程实现整个系统。
1.1 基本的框架
层次结构
分为Shell层和Core层
- Shell层用来处理人机交互,比如获取输入的命令,然后调用Core层的一些方法,最后如果需要的话,打印一些信息
- Core层用来写主要内核类(比如用来运行整个系统的Core类和作业PriorityRunnable类),或者存放一些数据结果,比如调度里面的队列。
1.2 调度原理
思考
-
如何让作业变为一个进程运行起来?
使用Java的并发编程,先把作业的类实现Runnable接口,接着传入Thread类,运行方法start即可。
-
PCB如何设计?
可以使用线程池来取代分配PCB给进程,这里有几个好处
- 线程池可以回收进程,节省资源
- 线程池可以设置最大的线程数量,实现PCB一样的功能,而且简单
-
如何修改默认的JVM对线程的调度
这也是最核心的问题,因为JVM的默认线程调度是抢占式优先级调度,如果要自己设计处理器对进程的低级调度,肯定不能直接去修改JVM的代码,那只有间接去修改。
非抢占式优先调度的解决方案(前提是处理机一次只能处理一个进程):
- 线程一旦创建,就会查看自己是不是就绪队列中优先级最高的线程并且处理机有没有正在处理其他的线程,如果不是且处理机空闲进入等待队列,如果是,那就送入处理机去继续运行。
- 处理机的线程结束,要通知等待队列中的最前面的线程。
- 等待队列中唤醒的线程重新执行1
追问,如何把一个进程送入等待队列
使用锁,把处理机当作一个临界资源,只有优先级高的线程有资格获取到锁。
2. Jan Language
通过自己制作出一门类似于Linux的Shell语言来实现对我们操作系统的控制,比如在一个txt文件里面敲代码,然后放到一个解释器类里面去运行。
3. 交互页面
编写Jan’s 解释器来实现人与OS的交互,页面类似Linux:
[local@root]# createThread
[local@root]#
操作命令:
-
createJob
创建作业 要求给他赋予名字,和优先级(输入数字)
提交刚刚创建的作业(高级调度为优先级调度),系统会自动根据PCB的个数,把作业调度到就绪队列中,如果不够,就先放到一个等待队列中
-
displayProcess
查看系统的进程
-
showRunning
查看正在处理机运行的作业
-
kill
按UID杀死进程
-
quit
退出系统
以上项目废除
JanOS 1.1
1. 概述图
2. 类图
3. 处理机模型
public class Processor {
/*
定义一些处理器的指令
*/
public static void ADD(Register r1,Register r2){
//把r1和r2相加的值存入r1
System.out.println(r1.getName()+" add "+r2.getName());
Core.usingTime(15);
r1.setData(r1.getData()+r2.getData());
}
public static void LOAD(int data, Register register) throws InterruptedException {
register.setData(data);
Core.usingTime(10);
System.out.println("executing LOAD");
System.out.println("put "+data+" into "+register.getName());
Thread.sleep(500);
}
public static int STORE(Register r) throws InterruptedException {
Core.usingTime(10);
System.out.println("executing STORE");
Thread.sleep(500);
return r.getData();
}
public static String visitReadMemory(int location) throws InterruptedException {
Core.usingTime(30);
System.out.println("reading Memory "+location);
Thread.sleep(500);
return Memory.read(location);
}
public static int changeLocation(int releventLocation,Register r) throws InterruptedException {
Core.usingTime(10);
System.out.println("changing location used register "+r.getName());
Thread.sleep(200);
return releventLocation+r.getData();
}
public static void visitWriteMemory(int data,int location) throws InterruptedException, IOException {
Core.usingTime(30);
Memory.write(location,data);
System.out.println("writing Memory "+location+" "+"data"+data);
Thread.sleep