赞
踩
目录
虽然我的兴趣是游戏开发,将来也打算从事这个行业。但是因为某些不可抗原因,我的大学专业和游戏开发关联性并不是很大。所以,我必须得学很多以后实际上并不怎么会用到的专业课知识。
比如操作系统。
上个学习操作系统的考试有多BT这里就不多说了,这个学期还有个折磨人的操作系统课设——并发环境以及进程低级调度的仿真实现。
(由于某些原因课设要求文档无法在这里全部发出,这里仅简要阐述需要完成的功能)
课设的主要要求包括但不局限于以上内容。而本文不会对以上各条目的实现进行详细讲解,只会对项目各模块进行大概介绍,以及运行结果的展示。
采用了Unity引擎主要做可视化的内容,同时操作系统核心代码也借助了协程的机制。
项目结构如下:
分别存储了 输入指令文件,输出日志结果文件。
分别存储了材质,预制体,场景(和可视化部分有关,与仿真系统核心无直接关联)
存储了操作系统核心代码。
在实现中,操作系统内核部分和可视化演示以及GUI界面部分是分离的。我是先写好并调试测试好仿真系统的代码,然后再写演示场景以及GUI部分(留出可以供外部调用的接口函数),然后再在仿真系统代码中相应的地方调用这些接口;同时为了防止循环调用等问题,还写了一个简易的事件系统,GUI界面的按钮触发信号通过事件系统传达给操作系统,从而作为用户的输入之一
(如下图)。
下面开始对这个项目的各个部分进行进一步的介绍。
这部分涉及太多的专业知识,全讲清楚的话估计要新开个专栏。这里只是简单略讲一下大致实现代码吧。
课设要求文件中有五个主要线程要实现:
(在具体实现中这五个线程都被抽象为了全局单例类)
而在具体实现中,我并没有用线程,而是借用了协程(所以他们每帧执行是有顺序的,这个地方有点投机取巧,不过有些线程安全问题就不用操心了)。
而这五个线程,在实际的实现中的关系,实际上类似于一个星形拓扑结构。核心的Linux2.6进程调度算法在ProcessScheduling_thread线程中实现,以这个线程为中心,通过调用其它线程的相关接口函数达到线程间的通信。
(部分代码图)
下面几句话简单介绍一下其它四个线程:
JobRequest_thread:用于新作业请求中断的仿真,常用鼠标双击事件而发生:假设计算机每10 秒查询一次外部是否有新作业的执行请求,在“并发作业请求文件”中判读是否有新进程请求运行。
InputBlock_thread:阻塞队列的唤醒线程。外设输入变量造成进程进入阻塞态,如键盘给变量赋值。
OutputBlock_thread:阻塞队列的唤醒线程。外设输出变量造成进程进入阻塞态, 如显示器显示。
PageInterruption_thread:处理缺页中断(LRU页面置换算法的实现)。
这部分主要用来可视化直观展示各个进程的调度过程。主要形式为固定视角的3D模型动画:
其中,每一个方块实体都代表一个进程,其上方会有红色的数字标注进程(作业)号。并且每个方块都会被随机分配一个颜色。
场景中主要有五个区域:最上方用来显示场景中现有的作业和进程的方块(如果新的作业进入后备队列就会在这一栏增加一个对应的方块,如果进程运行完毕退出系统则会在这一栏删除对应的进程)。下面从左往右如文字标注,分别是后备队列,就绪队列组,CPU,阻塞队列。
(如下图)
方块在这五个区域的实时行动轨迹则直观反映了进程在被调度过程中的周转轨迹。
此外还有个小细节,在方块预制体上放置了一个粒子系统,用来显示方块最近 一小段时间的行动轨迹(类似拖尾):
(同时拖尾的颜色和方块的颜色一致)
图形用户交互界面分为六个板块,如下图:
下面开始逐一介绍。
系统运行时各事件的日志信息都会输出在这里。
按要求,这个仿真系统采用页式存储管理,一共有16个内存块,每个进程分配4个,对于某个进程所分配的内存块,在这里都会实时用对应进程的方块的颜色填充:
这里显示了每个正在并发中的进程所对应的四个内存块中存储的页号信息,如果为-1则表示空(因为页号从0开始)。这里也是实时显示的,所以可以方便用来测试页面置换算法是否正确。
实时自动检测,如果方块为绿色则没有死锁,为红色则发生了死锁。
对应标注的信息会实时在这里显示,这个没啥好解释的叭。
开始按钮按了后会变为Disabled防止重复开始,结束按钮只有在开始按钮按完后才能按,同时也是只能按一次(因为结束后会对进程周转信息进行结算)。实时作业请求按钮是在运行过程中实时新增作业用的。然后滑动条是用来控制系统运行速度的(实际上就是调了一下timeScale)。
事件系统非常的简陋,主要就是写了一个Event基类:
- using System;
- namespace OS
- {
- /// <summary>
- /// 事件
- /// </summary>
- /// <typeparam name="T"></typeparam>
- public class Event<T> where T : Event<T>
- {
- private static Action mOnEvent;
-
- public static void Register(Action onEvent)
- {
- mOnEvent += onEvent;
- }
- public static void UnRegister(Action onEvent)
- {
- mOnEvent -= onEvent;
- }
- public static void Trigger()
- {
- mOnEvent?.Invoke();
- }
- }
-
- }
-
然后需要什么事件就写一个类继承这个基类,比如这样:
然后事件的注册注销和触发就全局调用事件对应的派生类即可。
最后运行一下整个流程吧:
一位游戏开发者的仿真操作系统课设
游戏开发真香!
文件 · master · 最爱番茄的土豆 / 操作系统课设_Unity3D · GitCode
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。