# 操作系统-时间片轮转调度算法模拟 **Repository Path**: atjyb/process-schedule-simulator ## Basic Information - **Project Name**: 操作系统-时间片轮转调度算法模拟 - **Description**: 长江大学计算机科学学院操作系统课程设计 - **Primary Language**: Java - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2023-05-26 - **Last Updated**: 2023-12-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 操作系统-时间片轮转调度算法模拟 #### 介绍 长江大学计算机科学学院操作系统课程设计 #### 软件架构 软件架构说明 《操作系统原理》课程设计 --进程调度模拟程序 一、课程设计目的 《操作系统原理》是计算机科学与技术专业的一门专业核心课程,也是研究生入学考试中计算机专业综合中所涉及的内容。该课程理论性强,纯粹的理论学习相对枯燥乏味,不易理解。通过课程设计,可加强学生对原理知识的理解。 二、课程设计的任务和要求 本次课程设计的题目是,时间片轮转调度算法的模拟实现。要求在充分理解时间片轮转调度算法原理的基础上,编写一个可视化的算法模拟程序。 具体任务如下: 1、根据需要,合理设计PCB结构,以适用于时间片轮转调度算法; 2、设计模拟指令格式,并以文件形式存储,程序能够读取文件并自动生成指令序列。 3、根据文件内容,建立模拟进程队列,并能采用时间片轮转调度算法对模拟进程进行调度。 任务要求: 1、进程的个数,进程的内容(即进程的功能序列)来源于一个进程序列描述文件。 2、需将调度过程输出到一个运行日志文件。 3、开发平台及语言不限(尽量避免使用python)。 4、要求设计一个Windows可视化应用程序。 三、模拟程序的描述: 模拟指令的格式:操作命令+操作时间 ● C : 表示在CPU上计算 ● I : 表示输入 ● O : 表示输出 ● W : 表示等待 ● H : 表示进程结束 操作时间代表该操作命令要执行多长时间(时间片个数)。这里假设I/O设备的数量没有限制,I和O设备都只有一类。 I,O,W三条指令实际上是不占有CPU的,执行这三条指令就应该将进程放入对应的等待队列(输入等待队列,输出等待队列 ,其他等待队列)。 例如,有一虚拟程序文件prc.txt描述如下,其中,指令后面的数值代表该指令需要执行的时间片个数,如C10,代表需要计算10个时间片: P1 C10 I20 C40 I30 C20 O30 H00 P2 I10 C50 O20 H00 P3 C10 I20 W20 C40 O10 H00................ 四、实验报告要求 除了编程实现设计的要求,在运行调试完成后,要书写出课程设计报告,总结归纳课设的各个方面,锻炼自己实践和总结报告的能力。课设报告正文部分不得少于5000字,要图文并茂。 课设报告的封面封底及参考目录见“操作系统课程设计报告封面目录封底.doc”。 五、参考资料 1. 汤小丹.计算机操作系统[M] 2. 严蔚敏.数据结构[M] 六、部份参考代码及界面 进程队列及结构图(仅供参考): 图1 PCB结构及队列模型 1. C++参考类: enum InstructionSet {INPUT,OUTPUT,WAIT,HALT,CALC}; //指令类 class CInstruction { friend class COsTestDlg; friend class PCB; public: CInstruction() { } ~CInstruction() { } CInstruction(InstructionSet iid,int rt) { m_nInstructionID=iid; m_nRunTime=rt; } private: CInstruction* m_pNextInstruction;//用于链接一个进程的所有指令成为链表(指令序列) int m_nRunTime;//本指令需要运行的时间长度(时间片个数) InstructionSet m_nInstructionID;//指令类型标识 }; //进程控制块类 class PCB { friend class COsTestDlg; public: PCB() { m_nPID=0; m_csProcessName=""; m_nRemainedTime=0;// m_pRuningInstruction=NULL; m_pInstructionList=NULL; m_pNextPCB=NULL; } //构造或创建一个进程 PCB(int pid,CString pname) { m_nPID=pid; m_csProcessName=pname; m_nRemainedTime=0;// m_pRuningInstruction=NULL; m_pInstructionList=NULL; m_pNextPCB=NULL; } ~PCB() { CInstruction* pTemp; while(m_pInstructionList) { m_pInstructionList=m_pInstructionList->m_pNextInstruction; pTemp=m_pInstructionList; delete pTemp; } } //本进程添加一条指令 void AppendInstruction(CInstruction* pInstruction) { CInstruction* pTempInstruction; if(m_pInstructionList==NULL) { //empty m_pInstructionList=pInstruction; } else { //more than one node pTempInstruction = m_pInstructionList; while(pTempInstruction->m_pNextInstruction!=NULL) pTempInstruction=pTempInstruction->m_pNextInstruction; pTempInstruction->m_pNextInstruction=pInstruction; } } private: PCB* m_pNextPCB; //进程队列的指针 int m_nPID; //进程标识符 CString m_csProcessName; //进程名字 int m_nRemainedTime; //当前运行指令运行还需要的时间 CInstruction* m_pRuningInstruction; //指向正在运行或将要运行的指令 CInstruction* m_pInstructionList; //指向本进程的指令序列(线性表)的第一条指令 }; PCB* m_pReadyPCBs;//就绪队列 PCB* m_pBackupReadyPCBs;//后备就绪队列 PCB* m_pInputWaittingPCBs;//输入等待队列 PCB* m_pOutputWaittingPCBs;//输出等待队列 PCB* m_pPureWaittingPCBs;//其他等待队列 int m_nTimeSlice;//时间片大小 void LoadPCBs(CString csFileName);//从文件中加载要试验的进程信息 void RemoveProcess(PCB* pPCB);//删除进程 void DoSchedule(); void RunOneTimeRange(PCB* pPCB,int nTime);//运行一个时间段 void TreadWaittingQueue(PCB* pWaittingPCBs);//处理某个等待队列,适时将完成进程移出到后备就绪队列。 void TreadAllWaittingQueues(); void AppendReadyQueue(PCB* pPCB);//pPCB所指节点添加到就绪队尾 void AppendBackupReadyQueue(PCB* pPCB);//pPCB所指节点添加到后备就绪队尾 void AppendWaitQueue(PCB* pPCB);//pPCB所指节点添加到等待队尾 void AppendInputQueue(PCB* pPCB);//pPCB所指节点添加到Input队尾 void AppendOutputQueue(PCB* pPCB);//pPCB所指节点添加到Output队尾 2. C#参考类及参考demo public class PCB { public string PName; //进程名称 public List PInstructions; //进程中的指令列表 public int CurrentInstruction; //当前运行指令索引 public PCB() { PInstructions = new List(); } } public class Instructions { public char IName; //指令类型 public double IRuntime; //指令运行时间 public double IRemainTime; //指令剩余运行时间 } //各类队列 AllQue = new List(); ReadyQue = new List(); BackupReadyQue = new List(); InputQue = new List(); OutputQue = new List(); WaitQue = new List(); 图2 打开文件 图3 调度过程 注1:图中的时间片大小指的是单位时间片对应的毫秒数,如图中所示值500,代表一个时间片的长度为500ms,对应C#中timer控件的Interval属性值。而指令C10代表计算10个时间片,按照前述设置,实际运行时共需500*10=5000ms。 注2:图中的就绪队列和后备就绪队列可以合并为一个,相应数据结构也可合并。 #### 安装教程 1. xxxx 2. xxxx 3. xxxx #### 使用说明 1. xxxx 2. xxxx 3. xxxx #### 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request #### 特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) 6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)