南京农业大学 操作系统 课程设计


前言

本人刚刚经历过南京农业大学的操作系统课程设计,深感无参考无代码无思路之抓狂,现将本人代码及思路记载如下,如果能帮助到有一些需要的人,那就是无上功德了。代码可能有奇奇怪怪的错误,思路上可能走了许多弯路,仅供参考。


一、课程设计要求简述

1. 多线程方面

至少用 5 个线程分别仿真作业请求、进程调度、输入输出处理、缺页中断处理、磁盘文件操作

2. 时间方面

时钟中断,并发使用,线程轮询每1秒有没有新的外部请求,调度时使用时间片轮转,假设计算机每 5 秒查询一次,判断是否有新作业的执行请求,由作业并发请求中断的线程单独实现。

3. 输入

输入两个文件,
1921812-jobs-input.txt 共有四项
作业序号(JobsID)
作业优先级(Priority)
作业请求时间(InTimes)
作业包含的程序指令数目(InstrucNum)
1.txt 2.txt… 也有四项
指令段编号(Instruc_ID)
用户程序指令的类型(Instruc_State)
用户程序指令访问的逻辑地址(L_Address)
每条指令运行时间(InRunTimes)

4. 输出

要求在窗口界面输出每秒程序运行情况,要求可以随时保存所有程序运行情况到txt文件中

5. 基础要求

◆基础硬件部件: CPU、内存、时钟中断、设备中断、MMU;
◆扩展硬件部件:缺页中断、缓冲区、磁盘交换区、磁盘等;
◆内存与硬盘:共 32KB,每个物理块大小 1024B,共 32 个物理块。10 个柱面,1 个柱面有 32 个磁道,1 个磁道中有 64 个扇区。假设 1 个扇区为 1 个物理块,每个物理块大小 1024B。
◆本文及代码完成的最基础要求。多任务作业并发环境下,实现 MMU 地址变换、作业
调度算法、进程原语、优先级+时间片轮转进程调度算法,位示图法实现连续空间动态分配。

二、大体思路讲解

1.从零开始的操作系统思路

1.1 作业要求梳理

从输入输出看起,接受的输入简单来说是两个级别:作业级别与指令级别

程序需要接受的输入是有几个作业,他们什么时候进入,在同时进入的时候先运行哪个其中有什么规则,此为程序需要解决的大问题
重点:何时更改运行的作业:新进入作业排序时,某作业完全运行成功时。

具体到作业,则是该作业运行时,该执行哪个指令了,该指令是什么类型,根据类型明白该指令是对内存做什么修改,以及知道运行多长时间,
重点:何时更改运行的指令:指令运行结束时,指令的上司作业被拿下时,指令因为进入阻塞状态而把CPU资源让给其他指令时。

不重要的:eclipse写界面应用程序,写好之后,复制到idea里面直接使用,较为方便

1.2 从文件中读取数据

总而言之,饭要一口一口吃,先解决从文件中读取数据到程序的数据结构中,使用起来既方便速度又快捷。对了,如果追求更高要求,就要考虑到在程序运行过程中更改作业文件,这样的情况下就要设置在程序运行过程中读取文件了,你看作业管理类是不是很适合兼职。

1.3 编写时钟类

多线程的最简单实现:使用Time与Schedule
不需要掌握所有用法,仅完成任务的话会使用即可。
在主函数的最初初始化:

static Timer timer= new Timer();

主类初始化运行时(每间隔1000ms启动ThreadTime线程,起始时间为0)

timer.schedule(new TheardTime(),0, 1000);

具体类中具体实现(重写run方法)

class TheardTime extends TimerTask{
    public void Schedule(){
    }
    public void run(){}

读取数据后中的任务,最重要最基础的就是时钟,所有类与进程与线程都依靠她进行,很简单的把之前的Timer的应用熟练一遍(查看2.1)

class TheardTime extends TimerTask{
    static int time = 0;
    static boolean limit = false;
    public void run() {
        //System.out.println(time + "!");
        ++time;
        limit=true;
    }
}

看我注释掉的代码,就是为了运行过程中方便查看,毕竟设断点调试也很麻烦,对了,idea这款编译器不错,导入项目导出包方便,快捷键什么的很多,关键是漂亮,颜值高,那还要什么自行车。

之后就是之前说的作业加载到系统中,再运行作业。

1.4 作业在CPU的全生命周期

1.4.1 准备–CPU静态类

首先将CPU静态类(含有CPU中必要的参数和CPU运行方法、以及低级调度方法,以及就绪队列和阻塞队列)编写出来,思考在作业执行过程中需要用到哪些参数,举例为:

PC程序计数器,
IR,
PSW程序CPU状态,
现在运行的进程序号及现在运行的进程命令种类,
L_Address指令逻辑地址(与MMU存储地址有关,先虚置),
timeslice时间片,
就绪队列以及阻塞队列,这里采用Queue,初始化采用LinkedList

static Queue<PCB> BqTimes =  new LinkedList<PCB>(); //就绪队列: 进程进入键盘输入阻塞队列时间

CPU中方法还包括
模拟低级调度:LowScheduling():快速排序

1.4.2 解决以什么顺序将进程装入CPU–编写进程调度进程类TheardSchedule

此类负责将作业装进CPU,切换作业,当作业需要执行时,将一切参数送进cpurun中执行作业,根据指令进行程序运行
具体逻辑为:
if c then s或者

if a[j]>a[j+1] then
          begin
            change:=true;
            temp:=a[j]; a[j]:=a[j+1]; a[j+1]:=temp;
          end;

if CPU空闲(PSW)then
	begin
	if 就绪队列不为空 then
		就绪队列队首出队列
	else
		显示空闲
	end
else
	begin
	if 时间片未用完 then
		执行进程,使用函数cpurun()
	else
		CPU中进程进入就绪队列
		进行低级调度
		时间片重置
		执行进程,使用函数cpurun()
	end
1.4.3 进程的退出与重新进入–编写IO管理进程类TheardIO

进程存在于CPU,何时退出,退出到阻塞队列或消失,何时进入新进程,何时进程阻塞队列
理论上管理程序输入与输出,实际上…
建议采用进程同步的读者写者修饰下

if 阻塞队列1不为空 then
	begin
	if 阻塞队列首时间到 then
		阻塞队列队首出队列
		更新阻塞队列时间
		塞进就绪队列(根据进入的调度算法排序就绪队列)
	else
	end
else if 阻塞队列2...不为空	

1.5 进程在CPU中执行

模拟CPU中如何运行进程:cpurun():推荐写于CPU静态类中
执行要求,打印log文件或System.out输出

1.6 保证程序运行到测试文件结束

2.具体问题的解决

2.1 极简作业调度算法

低级调度

核心采用折半排序,实际上是将优先级排序
稍微有点难度的反而是排序算法肯定是针对int的,但可以将队列先poll出来,再offer回去,中间排序算法针对的是int数组。
每次调用该算法记得要开头新建数组,结尾销毁数组因为每次的数组长度都会变。

慎重,极不严谨。

2.2 解决线程间唯一的冲突

时间管理专门类(专门将系统时间+1)应在进程调度之前,

很明显,其间有一个简单的先后关系,借鉴操作系统中的读者-写者问题,解决办法为加一个time类加上limit变量,此变量初始为false,TheardTime类运行结束后改为true,TheardSchedule运行开始前limit变量必须为true,运行完改为flase

2.3 五个线程一览

timer.schedule(new TheardTime(),0, 1000);//时间管理进程类:管理时钟与时钟按时间增加
timer_job.schedule(new TheardWork(),0,5000);//作业管理进程类:每5s检测是否有作业进入
timer_process.schedule(new TheardSchedule(),0,1000);//进程调度进程类,管理CPU的运行问题,并且和TheardTime通过变量实现先后关系
timer_io.schedule(new TheardIO(),0,1000);//IO管理进程类:管理程序输入与输出
timer_document.schedule(new ThreadDoc(),0,1000);//文件管理进程类:管理地址相关问题

2.4 MMU

要求三 连续存储空间:最简单的连续动态内存管理,MMU 地址变换,实际只需要设计数组即可(注意:需要适配要求,好运不可能每次)

(要求回顾)硬盘:10个柱面,1个柱面有32个磁道,1个磁道中有64个扇区。假设1个扇区为1个物理块,每个物理块大小1024B。
物理地址为 16 位。

数据存储的单位为双字节. 设计地址编码长度 需要符合要求。
假设1个扇 区为1个物理块,每个物理块大小1024B。 据视频亲口所说,是可以一个内存小块为一个物理块的,
所以全程序共分为20480个物理块 103264 个物理块 =20479 20480

5个进程的话,每个进程4096块
0-4096 4097-8192 8193-12288 12289-16384 16385-20480

逻辑地址,物理地址的计算 5个进程
每个进程23264=60*60 30条指令
每个都跳转, 不跳转+2,跳转的话加20(自己设定?)
所以最多利用每个进程4096中的600 ok
地址变化类
注意如果在程序运行中新增作业请求,此算法就会出现混乱,必须更改

    /**
     * 逻辑地址增加,顺序
     * @param add 原有逻辑地址
     * @return 现逻辑地址
     */

    static int enheng(int add){
        
    }
    /**
     * 逻辑地址增加,跳跃
     * @param add 原有逻辑地址
     * @return 现逻辑地址
     */

    static int enheng2(int add){
        
    }

    /**
     * 逻辑地址与物理地址转换
     * @param I 进程编号
     * @param add 逻辑地址
     * @return 物理地址
     */
    static int enheng3(int i,int add){
    }
}

以上是内存,先写出时间片与CPU运行

三、多线程相关总结

1.问题:主线程退出之后子线程依然运行

例子:主线程开启,子线程开启,主线程休眠3s,主线程结束,子线程依然运行
解决:给子线程加上守护线程

	childThread childThread1 = new childThread();
    childThread1.setDaemon(true);
    childThread1.start();

守护线程作用:
(1) thread.setDaemon(true)必须在thread.start()之前设置,否则会跑出一个IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。
(2) 在Daemon线程中产生的新线程也是Daemon的。
(3) 守护线程应该永远不去访问固有资源,如文件、数据库,因为它会在任何时候甚至在一个操作的中间发生中断。

守护线程作用:
如果用户线程已经全部退出运行了,只剩下守护线程存在了,虚拟机也就退出了。 因为没有了被守护者,守护线程也就没有工作可做了,也就没有继续运行程序的必要了。

四、 总结

呕心沥血之后再看,只觉风轻云淡,甚至有心情分享出来写博客。但当时我多么焦急多么无助,只有自己知道。诸位,莫避春阴上马迟,春来未有不阴时。
以上为2019届的课程设计,如果有问题,请私信我。

  • 14
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
目录 I 基础知识9 1 MINIX操作系统简介11 1.1 MINIX与UNIX . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.2 探索MINIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 1.3 编辑器:vi . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.4 编译器:CC . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 1.5 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2 Intel 8086体系结构19 2.1 8086 CPU结构. . . . . . . . . . . . . . . . . . . . . . . . . . 19 2.2 运算器与指令部件. . . . . . . . . . . . . . . . . . . . . . . . 19 2.3 寄存器组. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2.4 主存. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 2.5 堆栈. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 2.6 系统启动. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 2.7 二进制文件结构. . . . . . . . . . . . . . . . . . . . . . . . . . 25 3 ACK 8086汇编语言27 3.1 寻址. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3.2 数据移动指令. . . . . . . . . . . . . . . . . . . . . . . . . . . 28 3.3 常量、标号、数据与全局变量. . . . . . . . . . . . . . . . . . 29 3.4 运算指令. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 3.5 标志位操纵指令. . . . . . . . . . . . . . . . . . . . . . . . . . 31 3.6 串操作指令. . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 3.7 跳转、分支与循环. . . . . . . . . . . . . . . . . . . . . . . . 33 3.8 堆栈与子程序. . . . . . . . . . . . . . . . . . . . . . . . . . . 34 5 6 目录 4 实习:Hello World 37 4.1 Hello World程序. . . . . . . . . . . . . . . . . . . . . . . . . 37 4.2 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 II 汇编语言进阶41 5 C与汇编联合开发43 5.1 函数调用. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 5.2 全局与局部变量. . . . . . . . . . . . . . . . . . . . . . . . . . 45 5.3 编译与连接. . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 5.4 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 6 中断与I/O 49 6.1 中断. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 6.2 输入输出设备. . . . . . . . . . . . . . . . . . . . . . . . . . . 51 6.3 编写中断处理程序. . . . . . . . . . . . . . . . . . . . . . . . 51 6.4 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 7 实习:小游戏55 7.1 make工具. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 7.2 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 III 操作系统内核59 8 进程切换61 8.1 进程模型. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 8.2 进程的实现. . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 8.3 进程切换. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 8.4 中断嵌套. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 8.5 MiniOS中的进程切换. . . . . . . . . . . . . . . . . . . . . . . 68 8.6 操作系统实现原则. . . . . . . . . . . . . . . . . . . . . . . . 69 9 进程通信71 9.1 信号量. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 9.2 消息机制. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 9.3 消息机制的实现. . . . . . . . . . . . . . . . . . . . . . . . . . 76 9.4 调试消息内核. . . . . . . . . . . . . . . . . . . . . . . . . . . 78 目录7 10 实习:操作系统内核83 10.1 引导操作系统. . . . . . . . . . . . . . . . . . . . . . . . . . . 83 10.2 微内核与层次式操作系统结构. . . . . . . . . . . . . . . . . . 83 10.3 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 IV 轻量操作系统实现87 11 设备驱动程序89 11.1 设备驱动程序原理. . . . . . . . . . . . . . . . . . . . . . . . 89 11.2 键盘设备. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 11.3 屏幕设备. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 11.4 死锁的产生与预防. . . . . . . . . . . . . . . . . . . . . . . . 93 12 存储管理95 12.1 存储管理与系统调用服务进程. . . . . . . . . . . . . . . . . . 95 12.2 进程映像的创建与终止. . . . . . . . . . . . . . . . . . . . . . 97 12.3 替换进程映像. . . . . . . . . . . . . . . . . . . . . . . . . . . 98 13 文件系统101 13.1 文件与目录. . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 13.2 文件与目录管理. . . . . . . . . . . . . . . . . . . . . . . . . . 103 13.3 文件描述符. . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 14 实习:迷你操作系统109 14.1 一个简易的Shell . . . . . . . . . . . . . . . . . . . . . . . . . . 109 14.2 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 附录111 A vi常用命令113 B 虚拟机与外部的文件交换117
南京农业大学CSDN(中国软件开发者网)在南京农业大学中扮演着重要的角色。CSDN是一个知识分享和交流平台,为南京农业大学的计算机科学与技术学院的学生和教师提供了丰富的资源和机会。在这个平台上,学生可以分享他们的编程经验和解决问题的方法,教师可以发布他们的研究成果和教学经验。这种分享和交流的机制有助于促进学生之间的合作和共同进步,同时也为教师们提供了互相学习和优化课程的机会。 南京农业大学CSDN还提供了丰富多样的在线课程和培训资源,帮助学生提升他们的技术能力和专业知识。在这里,学生可以学习各种编程语言、软件开发技术和数据分析方法等,在实践中提升他们的技术实力。此外,CSDN还为学生提供了求职和实习的机会,与企业合作,实践他们所学的知识和技能。 通过参与南京农业大学CSDN,学生们还可以与其他高校的学生和社会上的专业人士进行交流,扩大他们的人脉和视野。在这里,学生们可以结识志同道合的朋友,互相学习和成长。此外,他们还可以通过CSDN的活动和比赛展示自己的才华和创新思维,提升他们的竞争力。 总的来说,南京农业大学CSDN为学生们提供了一个优质的学习和交流平台,帮助他们掌握专业知识,提升技术能力,拓宽视野,增强竞争力。在CSDN的引领下,南京农业大学的计算机科学与技术学院的学生们可以更好地适应社会发展的需求,成为有能力和创新思维的优秀计算机科学家和工程师。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值