进程调度程序设计报告(源代码)资料
进程调度程序设计

长沙学院课程设计说明书题目进程调度程序设计系(部) 计算机科学与技术系专业(班级) 2009级数据库二班姓名学号指导教师黄彩霞起止日期2012.6.4-2012.6.15课程设计任务书课程名称:操作系统课程设计设计题目:进程调度程序设计已知技术参数和设计要求:1. 设计任务设计一个虚拟内核,该内核能支持多任务管理。
提供创建进程、终止进程、进程状态转换,进程调度,上下文切换等功能。
2. 问题描述2.1 系统组成系统由虚拟内核(VKernel)、命令解释程序(Commander)、用户程序(Application)、编译器(Compiler)四部分组成。
VKernel首先运行,并常驻内存。
Kernel启动后,创建Commander进程。
根据用户请求创建多个Application进程。
Kernel负责维护6个数据结构,包括时间 (Time), 处理器状态(CPUstate),进程表(PCBTable), 就绪队列(ReadyState),等待队列(BlockedState),运行进程(RunningState)。
Time是系统时间片。
CPUstate应包括程序计数器PC,累加器A、B,状态寄存器F的值。
PCBTable的每一项是一个进程的进程控制块(PCB)。
Commander程序、Application程序是用下列CPU虚拟指令书写的程序:①CPU虚拟指令(以下指令仅供参考, 设计者可以自行设计)MOV n //把整数n赋给累加器ASAV m //把累加器A的值存入地址MADD n //从累加器A的值减去整数n,结果送到累加器A。
SUB n //从累加器A的值减去整数n,结果送到累加器A。
MUL n //从累加器A的值乘以整数n,结果送到累加器A。
DIV n //从累加器A的值除以整数n,结果送到累加器A。
JEQ m //F为0跳转到mJLG m //F大于0跳转到mJLE m //F大于等于0跳转到mJMP m //无条件跳转到mOUT port //累加器的内容输出到端口port。
操作系统实验报告进程调度

五邑大学实验报告操作系统课程2016~2017年度第1学期实验题目:进程调度院系:计算机学院班级: 140801学号: 3114002472姓名:黄凯鑫任课教师:白明成绩评定:实验二题目:进程调度完成日期:2016年12 月11 日1、实验目的(1)设计一个有n个进程工行的进程调度程序。
每个进程由一个进程控制块(PCB)表示。
进程控制块通常应包含下述信息:进程名、进程优先数、进程需要运行的时间、占用CPU的时间以及进程的状态等,且可按调度算法的不同而增删。
(2)调度程序应包含2~3种不同的调度算法,运行时可任意选一种,以利于各种算法的分析比较。
(3)系统应能显示或打印各进程状态和参数的变化情况,便于观察诸进程的调度过程2、实验内容(1)编制和调试示例给出的进程调度程序,并使其投入运行。
(2)自行设计或改写一个进程调度程序,在相应机器上调试和运行该程序,其功能应该不亚于示例。
(3)直观地评测各种调度算法的性能。
3、算法设计算法:(1) 优先数法。
进程就绪链按优先数大小从高到低排列,链首进程首先投入运行。
每过一个时间片,运行进程所需运行的时间片数减1,说明它已运行了一个时间片,优先数也减3,理由是该进程如果在一个时间片中完成不了,优先级应该降低一级。
接着比较现行进程和就绪链链首进程的优先数,如果仍是现行进程高或者相同,就让现行进程继续进行,否则,调度就绪链链首进程投入运行。
原运行进程再按其优先数大小插入就绪链,且改变它们对应的进程状态,直至所有进程都运行完各自的时间片数。
(2) 简单轮转法。
进程就绪链按各进程进入的先后次序排列,进程每次占用处理机的轮转时间按其重要程度登入进程控制块中的轮转时间片数记录项(相当于优先数法的优先数记录项位置)。
每过一个时间片,运行进程占用处理机的时间片数加1,然后比较占用处理机的时间片数是否与该进程的轮转时间片数相等,若相等说明已到达轮转时间,应将现运行进程排到就绪链末尾,调度链首进程占用处理机,且改变它们的进程状态,直至所有进程完成各自的时间片。
进程调度程序实验报告

一、实验目的通过本次实验,加深对进程调度原理和算法的理解,掌握进程调度程序的设计与实现方法。
实验要求我们使用高级编程语言编写一个简单的进程调度程序,实现不同调度算法的模拟,并通过实验验证算法的性能。
二、实验环境1. 操作系统:Windows 102. 编程语言:Java3. 开发工具:IntelliJ IDEA三、实验内容本次实验主要实现以下调度算法:1. 先来先服务(FCFS)2. 最短作业优先(SJF)3. 时间片轮转(RR)四、实验步骤1. 定义进程类(Process):```javapublic class Process {private String processName; // 进程名称private int arrivalTime; // 到达时间private int burstTime; // 运行时间private int waitingTime; // 等待时间private int turnaroundTime; // 周转时间// 构造函数public Process(String processName, int arrivalTime, int burstTime) {this.processName = processName;this.arrivalTime = arrivalTime;this.burstTime = burstTime;}// 省略getter和setter方法}```2. 定义调度器类(Scheduler):```javapublic class Scheduler {private List<Process> processes; // 进程列表private int currentTime; // 当前时间// 构造函数public Scheduler(List<Process> processes) {this.processes = processes;this.currentTime = 0;}// FCFS调度算法public void fcfs() {for (Process process : processes) {process.setWaitingTime(currentTime -process.getArrivalTime());currentTime += process.getBurstTime();process.setTurnaroundTime(currentTime -process.getArrivalTime());}}// SJF调度算法public void sjf() {processes.sort((p1, p2) -> p1.getBurstTime() -p2.getBurstTime());for (Process process : processes) {process.setWaitingTime(currentTime -process.getArrivalTime());currentTime += process.getBurstTime();process.setTurnaroundTime(currentTime -process.getArrivalTime());}}// RR调度算法public void rr(int quantum) {List<Process> sortedProcesses = new ArrayList<>(processes);sortedProcesses.sort((p1, p2) -> p1.getArrivalTime() -p2.getArrivalTime());int timeSlice = quantum;for (Process process : sortedProcesses) {if (process.getBurstTime() > timeSlice) {process.setWaitingTime(currentTime - process.getArrivalTime());currentTime += timeSlice;process.setTurnaroundTime(currentTime - process.getArrivalTime());process.setBurstTime(process.getBurstTime() - timeSlice);} else {process.setWaitingTime(currentTime - process.getArrivalTime());currentTime += process.getBurstTime();process.setTurnaroundTime(currentTime - process.getArrivalTime());process.setBurstTime(0);}}}}```3. 测试调度程序:```javapublic class Main {public static void main(String[] args) {List<Process> processes = new ArrayList<>();processes.add(new Process("P1", 0, 5));processes.add(new Process("P3", 4, 2));processes.add(new Process("P4", 6, 4));Scheduler scheduler = new Scheduler(processes); System.out.println("FCFS调度结果:");scheduler.fcfs();for (Process process : processes) {System.out.println(process);}processes = new ArrayList<>();processes.add(new Process("P1", 0, 5));processes.add(new Process("P2", 1, 3));processes.add(new Process("P3", 4, 2));processes.add(new Process("P4", 6, 4));System.out.println("SJF调度结果:");scheduler.sjf();for (Process process : processes) {System.out.println(process);}processes = new ArrayList<>();processes.add(new Process("P1", 0, 5));processes.add(new Process("P2", 1, 3));processes.add(new Process("P3", 4, 2));System.out.println("RR调度结果(时间片为2):");scheduler.rr(2);for (Process process : processes) {System.out.println(process);}}}```五、实验结果与分析通过实验,我们可以观察到以下结果:1. FCFS调度算法简单,但可能导致长作业等待时间过长。
实验三 进程调度(实验报告格式)

实验三:进程调度一、实验目的(1)理解进程控制块和进程组织方式;(2)掌握时间片轮转调度算法实现处理机调度。
二、实验环境微型计算机,Ubuntu Linux10.04 ,gedit,gcc三、实验内容1建立合理的PCB数据结构,建立含有8个进程结点的就绪队列,每个进程的要求运行时间随机产生,要求每个进程的要求运行时间不大于15。
2 设置时间片大小(3~6),使用时间片轮转调度算法实现处理机调度。
四、实验结果五、源代码#include<stdio.h>#include<time.h>#include<malloc.h>#define T 8#define NUM 10typedef struct PCB{int name;int runtime;int runedtime;int killtime;struct PCB *next;}PCB;PCB *creat_jiuxu(PCB *top){PCB *temp;int i;srand((int)time(0));for(i=0;i<NUM;i++){temp=(PCB *)malloc(sizeof(PCB));temp->name=i;temp->runtime=rand()%15;temp->runedtime=0;temp->next=NULL;temp->killtime=0;if(i==0) top=temp;else{temp->next=top;top=temp;}}return top;}void run(PCB *top){PCB *tail=top;if(tail->next!=NULL)tail=tail->next;PCB *rq=NULL;while(top!=NULL){rq=top;if(rq->runtime<=rq->runedtime+T){printf("process_name:%d,runtime:%d,killtime:%d\n",rq->name,rq->runtime,rq->killtime);/*if(rq!=NULL) free(rq);*/top=top->next;}else{top=top->next;rq->runedtime+=T;rq->killtime++;tail->next=rq;tail=rq;rq->next=NULL;}}return;}int main(){PCB *top=NULL;top=creat_jiuxu(top);run(top);return 0;}。
实验一、进程调度实验报告

实验一、进程调度实验报告一、实验目的进程调度是操作系统中的核心功能之一,其目的是合理地分配 CPU 资源给各个进程,以提高系统的整体性能和资源利用率。
通过本次实验,我们旨在深入理解进程调度的原理和算法,掌握进程状态的转换,观察不同调度策略对系统性能的影响,并通过实际编程实现来提高我们的编程能力和对操作系统概念的理解。
二、实验环境本次实验使用的操作系统为 Windows 10,编程语言为 C++,开发工具为 Visual Studio 2019。
三、实验原理1、进程状态进程在其生命周期中会经历不同的状态,包括就绪态、运行态和阻塞态。
就绪态表示进程已经准备好执行,只等待 CPU 分配;运行态表示进程正在 CPU 上执行;阻塞态表示进程由于等待某个事件(如 I/O操作完成)而暂时无法执行。
2、调度算法常见的进程调度算法有先来先服务(FCFS)、短作业优先(SJF)、时间片轮转(RR)等。
先来先服务算法按照进程到达的先后顺序进行调度。
短作业优先算法优先调度执行时间短的进程。
时间片轮转算法将 CPU 时间划分成固定大小的时间片,每个进程轮流获得一个时间片执行。
四、实验内容1、设计并实现一个简单的进程调度模拟器定义进程结构体,包含进程 ID、到达时间、执行时间、剩余时间等信息。
实现进程的创建、插入、删除等操作。
实现不同的调度算法。
2、对不同调度算法进行性能测试生成一组具有不同到达时间和执行时间的进程。
分别采用先来先服务、短作业优先和时间片轮转算法进行调度。
记录每个算法下的平均周转时间、平均等待时间等性能指标。
五、实验步骤1、进程结构体的定义```c++struct Process {int pid;int arrivalTime;int executionTime;int remainingTime;int finishTime;int waitingTime;int turnaroundTime;};```2、进程创建函数```c++void createProcess(Process processes, int& numProcesses, int pid, int arrivalTime, int executionTime) {processesnumProcessespid = pid;processesnumProcessesarrivalTime = arrivalTime;processesnumProcessesexecutionTime = executionTime;processesnumProcessesremainingTime = executionTime;numProcesses++;}```3、先来先服务调度算法实现```c++void fcfsScheduling(Process processes, int numProcesses) {int currentTime = 0;for (int i = 0; i < numProcesses; i++){if (currentTime < processesiarrivalTime) {currentTime = processesiarrivalTime;}processesistartTime = currentTime;currentTime += processesiexecutionTime;processesifinishTime = currentTime;processesiwaitingTime = processesistartTime processesiarrivalTime;processesiturnaroundTime = processesifinishTime processesiarrivalTime;}}```4、短作业优先调度算法实现```c++void sjfScheduling(Process processes, int numProcesses) {int currentTime = 0;int minExecutionTime, selectedProcess;bool found;while (true) {found = false;minExecutionTime = INT_MAX;selectedProcess =-1;for (int i = 0; i < numProcesses; i++){if (processesiarrivalTime <= currentTime &&processesiremainingTime < minExecutionTime &&processesiremainingTime > 0) {found = true;minExecutionTime = processesiremainingTime;selectedProcess = i;}}if (!found) {break;}processesselectedProcessstartTime = currentTime;currentTime += processesselectedProcessremainingTime;processesselectedProcessfinishTime = currentTime;processesselectedProcesswaitingTime =processesselectedProcessstartTime processesselectedProcessarrivalTime;processesselectedProcessturnaroundTime =processesselectedProcessfinishTime processesselectedProcessarrivalTime;processesselectedProcessremainingTime = 0;}}```5、时间片轮转调度算法实现```c++void rrScheduling(Process processes, int numProcesses, int timeSlice) {int currentTime = 0;Queue<int> readyQueue;for (int i = 0; i < numProcesses; i++){readyQueueenqueue(i);}while (!readyQueueisEmpty()){int currentProcess = readyQueuedequeue();if (processescurrentProcessarrivalTime > currentTime) {currentTime = processescurrentProcessarrivalTime;}if (processescurrentProcessremainingTime <= timeSlice) {currentTime += processescurrentProcessremainingTime;processescurrentProcessfinishTime = currentTime;processescurrentProcesswaitingTime =processescurrentProcessstartTime processescurrentProcessarrivalTime;processescurrentProcessturnaroundTime =processescurrentProcessfinishTime processescurrentProcessarrivalTime;processescurrentProcessremainingTime = 0;} else {currentTime += timeSlice;processescurrentProcessremainingTime = timeSlice;readyQueueenqueue(currentProcess);}}}```6、性能指标计算函数```c++void calculatePerformanceMetrics(Process processes, int numProcesses, double& averageWaitingTime, double& averageTurnaroundTime) {double totalWaitingTime = 0, totalTurnaroundTime = 0;for (int i = 0; i < numProcesses; i++){totalWaitingTime += processesiwaitingTime;totalTurnaroundTime += processesiturnaroundTime;}averageWaitingTime = totalWaitingTime / numProcesses; averageTurnaroundTime = totalTurnaroundTime / numProcesses;}```7、主函数```c++int main(){Process processes100;int numProcesses = 0;//创建进程createProcess(processes, numProcesses, 1, 0, 5);createProcess(processes, numProcesses, 2, 1, 3);createProcess(processes, numProcesses, 3, 2, 4);createProcess(processes, numProcesses, 4, 3, 2);//先来先服务调度fcfsScheduling(processes, numProcesses);double fcfsAverageWaitingTime, fcfsAverageTurnaroundTime;calculatePerformanceMetrics(processes, numProcesses, fcfsAverageWaitingTime, fcfsAverageTurnaroundTime);cout <<"先来先服务调度的平均等待时间:"<<fcfsAverageWaitingTime << endl;cout <<"先来先服务调度的平均周转时间:"<<fcfsAverageTurnaroundTime << endl;//短作业优先调度sjfScheduling(processes, numProcesses);double sjfAverageWaitingTime, sjfAverageTurnaroundTime;calculatePerformanceMetrics(processes, numProcesses, sjfAverageWaitingTime, sjfAverageTurnaroundTime);cout <<"短作业优先调度的平均等待时间:"<<sjfAverageWaitingTime << endl;cout <<"短作业优先调度的平均周转时间:"<<sjfAverageTurnaroundTime << endl;//时间片轮转调度(时间片为 2)rrScheduling(processes, numProcesses, 2);double rrAverageWaitingTime, rrAverageTurnaroundTime;calculatePerformanceMetrics(processes, numProcesses, rrAverageWaitingTime, rrAverageTurnaroundTime);cout <<"时间片轮转调度(时间片为 2)的平均等待时间:"<< rrAverageWaitingTime << endl;cout <<"时间片轮转调度(时间片为 2)的平均周转时间:"<< rrAverageTurnaroundTime << endl;return 0;}```六、实验结果与分析1、先来先服务调度平均等待时间:40平均周转时间:85分析:先来先服务调度算法简单直观,但对于短作业可能会造成较长的等待时间,导致平均等待时间和平均周转时间较长。
操作系统原理 实验一:进程调度实验报告书-模板

计算机科学系实验报告书课程名:《操作系统原理》题目:进程调度班级:学号:姓名:操作系统原理实验——进程调度实验报告一、目的与要求1)进程是操作系统最重要的概念之一,进程调度是操作系统内核的重要功能,本实验要求用C 语言编写一个进程调度模拟程序,使用优先级或时间片轮转法实现进程调度。
本实验可加深对进程调度算法的理解。
2)按照实验题目要求独立正确地完成实验内容(编写、调试算法程序,提交程序清单及及相关实验数据与运行结果)3)于2012年10月22日以前提交本次实验报告(含电子和纸质报告,由学习委员以班为单位统一打包提交)。
2 实验内容或题目1)设计有5个进程并发执行的模拟调度程序,每个程序由一个PCB表示。
2)模拟调度程序可任选两种调度算法之一实现(有能力的同学可同时实现两个调度算法)。
3)程序执行中应能在屏幕上显示出各进程的状态变化,以便于观察调度的整个过程。
4)本次实验内容(项目)的详细说明以及要求请参见实验指导书。
3 实验步骤与源程序实验步骤:1、理解本实验中关于两种调度算法的说明。
2、根据调度算法的说明,画出相应的程序流程图。
3、按照程序流程图,用C语言编程并实现。
源程序:#include <stdlib.h>/*进程调度优先权法*/#include <stdio.h>#include <time.h>#define null 0struct PCB{int id;int prior;int used;int need;int run;char status;struct PCB * next;};main(){struct PCB *head,*rear,*temp,*run,*small,*p,*q;int i,j,t;printf("优先权进程调度算法\n\n 5个初始进程详细信息如下:\n\n");printf("\t进程号\t优先级\tused\tneed\t状态\t下一PCB\n\n");head=null;rear=null;for(i=1;i<=5;i++) { //动态生成含5个元素的队列temp=malloc(sizeof(struct PCB)); //动态分配一个PCB temp->id=i;temp->prior=rand()%5;temp->status='W';temp->next=null;if (head==null){head=temp;rear=head;}else{rear->next=temp;rear=temp;}}temp=head;while(temp!=null){printf("\t%d\t%d\t%c\t%d\n",temp->id,temp->prior,temp->status,temp->next);temp=temp->next;}getchar(); //让程序停下来,可以查看结果。
操作系统课程设计报告进程调度

前言操作系统(Operating System, 简称OS)是管理和控制计算机硬件与软件资源旳计算机程序, 是直接运营在“裸机”上旳最基本旳系统软件, 任何其他软件都必须在操作系统旳支持下才干运营。
操作系统是顾客和计算机旳接口, 同步也是计算机硬件和其他软件旳接口。
操作系统旳功能涉及管理计算机系统旳硬件、软件及数据资源, 控制程序运营, 改善人机界面, 为其他应用软件提供支持, 让计算机系统所有资源最大限度地发挥作用, 提供多种形式旳顾客界面, 使顾客有一种好旳工作环境, 为其他软件旳开发提供必要旳服务和相应旳接口等。
事实上, 顾客是不用接触操作系统旳, 操作系统管理着计算机硬件资源, 同步按照应用程序旳资源祈求, 分派资源, 如: 划分CPU时间, 内存空间旳开辟, 调用打印机等。
操作系统旳重要功能是资源管理, 程序控制和人机交互等。
计算机系统旳资源可分为设备资源和信息资源两大类。
设备资源指旳是构成计算机旳硬件设备, 如中央解决器, 主存储器, 磁盘存储器, 打印机, 磁带存储器, 显示屏, 键盘输入设备和鼠标等。
信息资源指旳是寄存于计算机内旳多种数据, 如系统软件和应用软件等。
操作系统位于底层硬件与顾客之间, 是两者沟通旳桥梁。
顾客可以通过操作系统旳顾客界面, 输入命令。
操作系统则对命令进行解释, 驱动硬件设备, 实现顾客规定。
本次课程设计我们将对上学期所学旳知识进行系统旳应用, 而达到巩固知识旳作用目录1问题概述 (2)2需求分析 (2)3 概要设计 (2)3.1重要功能 (2)3.2 模块功能构造 (3)3.3 软硬件环境 (3)3.4数据构造设计 (3)4 具体设计 (4)4.1“先来先服务(FCFS)调度算法” (4)4.2“短进程调度算法(SPF)” (7)4.3“高响应比优先调度算法” (10)4.4“优先级调度(非抢占式)算法” (13)5 系统测试及调试 (15)5.1测试 (15)5.2调试过程中遇到旳问题 (16)6 心得体会 (17)7 参照文献 (18)8 附录 (19)1问题概述编写一种进程调度程序, 容许多种进程并发执行。
进程的调度实验报告(3篇)

第1篇一、实验目的通过本次实验,加深对操作系统进程调度原理的理解,掌握先来先服务(FCFS)、时间片轮转(RR)和动态优先级(DP)三种常见调度算法的实现,并能够分析这些算法的优缺点,提高程序设计能力。
二、实验环境- 编程语言:C语言- 操作系统:Linux- 编译器:GCC三、实验内容本实验主要实现以下内容:1. 定义进程控制块(PCB)结构体,包含进程名、到达时间、服务时间、优先级、状态等信息。
2. 实现三种调度算法:FCFS、RR和DP。
3. 创建一个进程队列,用于存储所有进程。
4. 实现调度函数,根据所选算法选择下一个执行的进程。
5. 模拟进程执行过程,打印进程执行状态和就绪队列。
四、实验步骤1. 定义PCB结构体:```ctypedef struct PCB {char processName[10];int arrivalTime;int serviceTime;int priority;int usedTime;int state; // 0: 等待,1: 运行,2: 完成} PCB;```2. 创建进程队列:```cPCB processes[MAX_PROCESSES]; // 假设最多有MAX_PROCESSES个进程int processCount = 0; // 实际进程数量```3. 实现三种调度算法:(1)FCFS调度算法:```cvoid fcfsScheduling() {int i, j;for (i = 0; i < processCount; i++) {processes[i].state = 1; // 设置为运行状态printf("正在运行进程:%s\n", processes[i].processName); processes[i].usedTime++;if (processes[i].usedTime == processes[i].serviceTime) { processes[i].state = 2; // 设置为完成状态printf("进程:%s 完成\n", processes[i].processName); }for (j = i + 1; j < processCount; j++) {processes[j].arrivalTime--;}}}```(2)RR调度算法:```cvoid rrScheduling() {int i, j, quantum = 1; // 时间片for (i = 0; i < processCount; i++) {processes[i].state = 1; // 设置为运行状态printf("正在运行进程:%s\n", processes[i].processName); processes[i].usedTime++;processes[i].serviceTime--;if (processes[i].serviceTime <= 0) {processes[i].state = 2; // 设置为完成状态printf("进程:%s 完成\n", processes[i].processName); } else {processes[i].arrivalTime++;}for (j = i + 1; j < processCount; j++) {processes[j].arrivalTime--;}}}```(3)DP调度算法:```cvoid dpScheduling() {int i, j, minPriority = MAX_PRIORITY;int minIndex = -1;for (i = 0; i < processCount; i++) {if (processes[i].arrivalTime <= 0 && processes[i].priority < minPriority) {minPriority = processes[i].priority;minIndex = i;}}if (minIndex != -1) {processes[minIndex].state = 1; // 设置为运行状态printf("正在运行进程:%s\n", processes[minIndex].processName);processes[minIndex].usedTime++;processes[minIndex].priority--;processes[minIndex].serviceTime--;if (processes[minIndex].serviceTime <= 0) {processes[minIndex].state = 2; // 设置为完成状态printf("进程:%s 完成\n", processes[minIndex].processName); }}}```4. 模拟进程执行过程:```cvoid simulateProcess() {printf("请选择调度算法(1:FCFS,2:RR,3:DP):");int choice;scanf("%d", &choice);switch (choice) {case 1:fcfsScheduling();break;case 2:rrScheduling();break;case 3:dpScheduling();break;default:printf("无效的调度算法选择。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课程设计报告题 目 进程调度程序设计课 程 名 称 操作系统课程设计院 部 名 称 计算机工程学院专 业 计算机科学与技术班 级 13计算机科学与技术(单)(1) 学 生 姓 名 周敏健学 号 1305201013课程设计地点 A104课程设计学时 20学时指 导 教 师 何 健金陵科技学院教务处制 成绩目录摘要 (3)一、课程设计的目的和要求 (4)二、系统需求分析 (4)三、总体设计 (5)四、详细设计 (6)五、测试、调试过程 (9)六、结论与体会 (11)七、参考文献 (12)附录:源程序 (12)课程设计课题进程调度程序设计摘要在多道系统中,对批处理作业需要进行作业调度。
作业调度是在资源满足的条件下,将处于就绪状态的作业调入内存,同时生成与作业相对应的进程,并未这些进程提供所需要的资源。
进程调度需要根据进程控制块(PCB)中的信息,检查系统是否满足进程的资源需求。
只有在满足进程的资源需求的情况下,系统才能进行进程调度。
下面是几种常见的作业调度算法:先来先服务(FCFS)、优先算法、轮换算法、短作业优先算法以及最高响应比优先法等,本文将对前两种算法进行详细的介绍。
关键词:进程调度,优先级,FCFS,PCB,作业,资源一、课程设计的目的和要求1、目的进程调度是处理机管理的核心内容。
本设计要求用C语言编写和调试一个简单的进程调度程序。
通过设计本可以加深理解有关进程控制块、进程队列的概念,并体会和了解最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法的具体实施办法。
2、要求1)进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法。
2)每个进程有一个进程控制块(PCB)表示。
进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。
3)进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。
进程的到达时间为进程输入的时间。
进程的运行时间以时间片为单位进行计算。
4)每个进程的状态可以是就绪W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。
5)就绪进程获得CPU后都只能运行一个时间片。
用已占用CPU时间加1来表示。
如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。
6)每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查。
7)重复以上过程,直到所要进程都完成为止。
二、系统需求分析编写一个模拟进程调度的程序,将每个进程抽象成一个进程控制块PCB,PCB 用一个结构体描述。
采用两种不同的调度算法来实现功能,主要有如下几大功能模块组成。
(1)创建优先数PCB模块用循环来实现对每个进程的进程名、进程优先数(随机分配)以及所需时间的录入。
将进程队列存放到就绪队列等待执行。
(2)优先数调度算法模块从优先级最高(就绪队列的第一个进程)的开始执行,每执行一次优先数减1,并重新放入就绪队列进行排序,对排序完的继续运行直到所有进程都结束。
(3)FCFS创建PCB模块对N个进程的信息进行输入:进程名、到达时间、需要时间等。
每输入一个进程,按进程的到达时间进行排序,记下前驱和后继的方法。
(4)FCFS调度算法模块当系统时间与第一个进程到达时间一致时,将进程状态置为Run,直到这个进程执行完,再判断下个进程的到达时间,若系统时间大于下个进程的到达时间,即上个进程的结束时间就是下个进程的开始时间,反之就等待系统时间。
进程结束后放入完成队列。
(5)主函数及菜单显示由主菜单进入显示界面,进行算法选择。
三、总体设计进程是程序在处理机上的执行过程。
进程存在的标识是进程控制块(PCB),所谓系统创建一个进程,就是由系统为某个程序设置一个PCB,用于对该进程进行控制和管理。
进程任务完成,由系统收回其PCB,该进程便消亡。
每个进程可有三个状态:运行状态、就绪状态和完成状态。
因此设计三个链队列,finish 为完成队列的头指针,wait为就绪队列的头指针。
因为每一时刻,CPU只能运行一个进程,所以运行队列只有一个run指针指向当前运行的进程。
考虑到处理的方便,将它们设为全局变量。
总体结构框架图:四、详细设计(1)优先数调度算法优先调度算法要为每一个进程设一个优先数,它总是把处理机给就绪队列中具有最高优先权的进程。
常用的算法有静态优先权法和动态优先权法。
本程序采用了动态优先权法,使进程的优先权随时间而改变。
初始的进程优先数取决于进程运行所需的时间,时间大,则优先数低,所以采取了将进程优先数定位最大的那个进程,随着进程的运行优先数进行调整,每次运行时都是从就绪队列中选取优先数最大的进程运行,所以将就绪队列按照优先数的大小从高到低排序,这样,每次取队头进程即可。
优先数算法 界面F C F S 算法开始(2)先来先服务调度算法先来先服务调度算法是按照进程进入就绪队列的先后顺序调度并分配处理机执行。
先来先服务算法是一种不可抢占的算法,先进入就绪队列的进程,先被处理机运行,一旦一个进程占有了处理机,它就一直运行下去,直到该进程完成工作或者因为等待某种事件而不能继续运行时才释放处理机。
优先数调度算法输入进程信息将进程放入ready 队列进程按优先数大小排序 取ready 队列首进程送入run执行一个时间片,优先数-1,运行时间+1是否还需输入进程 YN 输入时进程是否完成N执行队列时 放入完成队列YFCFS 调度算法输入进程信息将进程放入ready 队列进程按到达先后顺序排序 取ready 队列首进程送入run执行一个时间片,运行时间+1是否还需输入进程 YN 输入时进程是否完成 N执行队列时 放入完成队列Y五、测试、调试过程界面优先数算法输入优先数算法输出FCFS算法输入FCFS算法输出遇到的问题:在设计程序时,在算法上面出现了一些错误,优先数不是由大到小排序,而是应该这样理解,当进程执行一个时间片时,优先数减一(使用CPU的时间变少,反而优先级高),因此,优先级高的优先数应该是比较小的,而不是优先数大的优先级大。
在程序调试时,链表发生了错误,该内存不可写或者就是程序直接结束,但最终结果不是我想要的,经过一番折腾,最后发现,头指针和头结点混淆,有些地方没有给指针分配内存,语句的先后顺序不正确,以及没有考虑到链表最后没有设置结束标志。
六、结论与体会做这个程序我断断续续的算下来应该总共用了2天,主要是花时间在观察别人的算法读别人的程序,然后才开始写自己的程序,期间参考了前人的程序并进行了改善和加工,这让我对进程调度的理解再次加深了,这是在平常学习的基础上,与程序相结合的过程,让我再次感受到编程给我们带来的无穷魅力,只要自己有兴趣,其实编程也是一件有趣的事,为了达到一定的要求,我们必须多次尝试用不同的方法去实现它,比如,进程调度有先来先服务算法,对于这个算法,可以用数组实现,也可以用链表实现,但是到底哪个更好哪个更灵活呢,相信学过C语言的人都知道肯定是用链表实现最好了。
这次设计还是有一些不足之处的,比如在算法和运行效率上还是有些欠缺的,需要进一步去改善程序代码,提高效率,减少冗余和错误,让使用者更清晰的观察和理解进程调度。
七、参考文献[1]任爱华、罗晓峰. 操作系统实用教程(第三版)[M].北京:清华大学出版社,2009[2]谌卫军、王浩娟. 操作系统[M]. 北京:清华大学出版社,2012.5[3](日)前桥和弥(Maebasi Kazuya). 征服C指针[M]. 吴雅明译. 北京:人民邮电出版社,2013.2附录:源程序#include<stdio.h>#include<stdlib.h>#include<string.h>#include<windows.h>#include<time.h>typedef struct node{char name[10]; //进程名int prio; //进程优先数int cputime; //进程占用CPU时间int needtime; //进程到完成还要的时间int arrivetime; //进程到达时间int starttime; //进程开始时间int finishtime; //进程完成时间int servicetime; //进程服务时间char state; //进程的状态struct node *next;}PCB;PCB *finish,*ready,*run; //队列指针int N; //进程量void firstin(){run=ready; //就绪队列头指针赋值给运行头指针run->state='R'; //进程状态变为运行态ready=ready->next; //就绪对列头指针后移到下一进程}void prt1(char a){switch(a){case 1: /*优先数法*/printf("名字\t进程占用CPU时间\t需要的时间\t优先级数\t状态\n");break;case 2: /*先来先服务算法*/printf("名字\t到达时间\t开始时间\t服务时间\t完成时间\t状态\n");break;default:break;}}void prt2(char a,PCB *q){switch(a){case 1:printf("%s\t%d\t\t%d\t\t%d\t\t%c\n",q->name,q->cputime,q->needtime,q->prio,q->state);break;case 2:printf("%s\t%d\t\t%d\t\t%d\t\t%d\t\t%c\n",q->name,q->arrivetime,q->starttime,q->servicetim e,q->finishtime,q->state);break;default:break;}}void prt(char algo){PCB *p;prt1(algo); //输出文字格式if(run!=NULL) //如果运行指针不空prt2(algo,run); //输出当前正在运行的PCBp=ready; //输出就绪队列PCBwhile(p!=NULL){prt2(algo,p);p=p->next;}p=finish; //输出完成队列的PCBwhile(p!=NULL){prt2(algo,p);p=p->next;}getchar(); //压任意键继续}void insert1(PCB *q){PCB *p1,*s,*r;int b;s=q; //待插入的PCB指针p1=ready; //就绪队列头指针r=p1; //做p1的前驱指针b=1;while((p1!=NULL)&&b) //根据优先数确定插入位置if(p1->prio>=s->prio){r=p1;p1=p1->next;}elseb=0;if(r!=p1) //如果条件成立说明插入在r与p1之间{r->next=s;s->next=p1;}else{s->next=p1; //否则插入在就绪队列的头ready=s;}}void insert2(PCB *q){PCB *p1,*s,*r;int b;s=q; //指针s指向新要插入的进程p1=ready; //指针p1指向原来的进程的对首r=p1; //使用指针r指向p1前面的进程b=1;while((p1!=NULL)&&b){if(p1->arrivetime<s->arrivetime){r=p1;p1=p1->next;}elseb=0;}if(r!=p1){r->next=s;s->next=p1;}else{s->next=p1;ready=s;}}void create1(char alg){PCB *p;int i,time;char na[10];ready=NULL; //就绪队列头指针finish=NULL; //完成队列头指针run=NULL; //运行队列头指针//输入N个进程名和所需时间创建PCBfor(i=1;i<=N;i++){printf("请输入第%d个进程的名字和运行时间\n进程名:",i);p=(PCB *)malloc(sizeof(PCB));scanf("%s",na);printf("所需时间:");scanf("%d",&time);strcpy(p->name,na);p->cputime=0;p->needtime=time;p->state='W';p->prio=rand()%15+1; //随机分配优先数[1,15]if(ready!=NULL) //就绪队列不空则调用插入函数插入insert1(p); //对新进程插入就绪队列else{p->next=ready; //创建就绪队列的第一个PCBready=p;}}system("cls");printf(" 优先数算法结果输出\n");printf("---------------------------------------------------------------------------\n");prt(alg); //输出进程PCB信息run=ready; //将就绪队列的第一个进程投入运行ready=ready->next;run->state='R';}void create2(char alg){PCB *p;int i;ready=NULL;run=NULL;finish=NULL;for(i=0;i<N;i++){p=(PCB *)malloc(sizeof(PCB));printf("进程名:");scanf("%s",p->name);printf("到达时间:");scanf("%d",&p->arrivetime);printf("需要时间:");scanf("%d",&p->servicetime);p->starttime=0;p->finishtime=0;p->state='W';if(ready!=NULL)insert2(p);//将新进程插入就绪队列else{p->next=ready;//创建就绪队列的第一个ready=p;}}system("cls");printf(" 先来先服务算法结果输出\n");printf("---------------------------------------------------------------------------\n");prt(alg);}void priority(char alg){while(run!=NULL) //当运行队列不空时,有进程正在运行{run->cputime=run->cputime+1;run->needtime=run->needtime-1;run->prio=run->prio-1; //每运行一次优先数-1if(run->prio<0) //如果优先数减到小于0,则转换成0run->prio=0;if(run->needtime==0) //如果所需时间为0,即完成,将其插入完成队列{run->next=finish;finish=run;run->state='F'; //置状态为完成态run=NULL; //运行队列头指针为空if(ready!=NULL) //如果就绪队列不空firstin(); //将就绪对列的第一个进程投入运行}else //没有运行完同时优先数不是最大,则将其变为就绪态插入到就绪队列if((ready!=NULL)&&(run->prio<ready->prio)){run->state='W'; //状态改为就绪insert1(run); //将进程按优先数大小插入firstin(); //将就绪队列的第一个进程投入运行}prt(alg); //输出进程PCB信息}}void FCFS(char alg){ int time=0;//系统时间从0开始do{run=ready;//就绪序列的第一个进程放入run队列进行执行run->state='R';//进程开始执行ready=ready->next;//指向下一个time=run->arrivetime>time? run->arrivetime:time;run->starttime=time;//进程开始prt(alg);//显示正在执行的进程time=time+run->servicetime;//计算下个进程最小可开始时间run->finishtime=time;//进程结束时间run->state='F';//结束状态标识prt(alg);//进程结束再显示run->next=finish;finish=run;//进程结束放入结束队列run=NULL;}while(ready!=NULL);}/*菜单显示函数*/void Menu(){system("cls");printf("\t\t+━━━━━━━━━━━━━━━━━━━━━━+\n");printf("\t\t| 进程调度算法| \n");printf("\t\t|━━━━━━━━━━━━━━━━━━━━━━| \n");printf("\t\t| | \n");printf("\t\t| [1]优先数算法| \n");printf("\t\t| | \n");printf("\t\t| [2]先来先服务算法| \n");printf("\t\t| | \n");printf("\t\t| [3]退出系统| \n");printf("\t\t| | \n");printf("\t\t|━━━━━━━━━━━━━━━━━━━━━━| \n");printf("\t\t| By:周敏健| \n");printf("\t\t+━━━━━━━━━━━━━━━━━━━━━━+\n");printf("\t\t请输入编号:");}int main(){char algo; //接收算法编号char mainmenu;//判断是否继续srand((unsigned)time(NULL));system("cls");//清屏do{Menu();//显示菜单scanf("%d",&algo); //输入算法编号switch(algo){case 1:system("cls");printf("您选择的是优先数算法\n");printf("请输入进程数目:");scanf("%d",&N); //输入进程数create1(algo); //创建队列priority(algo);//优先数break;case 2:system("cls");printf("您选择的是先来先服务算法\n");printf("请输入进程数目:");scanf("%d",&N); //输入进程个数create2(algo);//创建队列FCFS(algo);//先来先服务break;case 3:printf("\t\t再见! \n");exit(0);break;default:printf("输入有误\n");break;}printf("\n是否继续操作(Y/N) ");fflush(stdin);mainmenu=getchar();}while(mainmenu=='y'||mainmenu=='Y');return 0;}。