实验三 单处理器系统的进程调度

合集下载

进程调度实验报告

进程调度实验报告

进程调度实验报告
实验名称实验三进程调度
⼀.实验⽬的
了解进程的调度机制,掌握短作业优先算法、时间⽚轮转算法(RR)和优先数算法,并理解响应时间和周转时间的意义。

⼆.实验内容
模拟短作业优先算法、时间⽚轮转算法(RR)和优先数算法的执⾏情况,并动态画出其进程执⾏的 Gantt 图,计算以上算法的每个进程的响应时间和周转时间。

三.实验步骤和结果
1、需要模拟执⾏的进程序列如下:
进程名到达时间运⾏时间优先数
P1 0 7 5
P2 1 1 1
P3 1 3 4
P4 2 5 3
P5 4 4 2
假设:优先数越⼩优先级越⾼;所有进程都是纯 CPU 型进程。

请把上表的数据按照你⾃⼰设计的格式存为⼀个⽂本⽂件 JOB1.TXT。

2、编写⼀个模拟程序,可以读⼊⽂本⽂件 JOB1.TXT 中描述的进程序列,然后模拟短作业优先算法、时间⽚轮转算法(RR)和优先数算法的执⾏情况,并动态画出其进程执⾏的 Gantt 图,计算以上算法的每个进程的响应时间和周转时间。

3、读⼊⽂本⽂件 JOB1.TXT 中描述的进程序列,按照短作业优先算法执⾏程序。

4、按照时间⽚轮转算法执⾏程序时间⽚⼤⼩分布为 1、2 和 3。

5、按照优先数算法执⾏程序。

程序执⾏结果见下图:
第1页,共2页
教务处制
四.实验总结
通过这次试验,我们更加深刻地理解了有关于进程调度的内容,响应时间就是进程刚开始被执⾏的时间,等待时间就是进程在就绪队列中等待的时间,周转时间就是进程被执⾏完毕的时间(包括等待进⼊内存的时间,在就绪队列中的等待时间,执⾏时间,I/O时间)。

实验三 模拟进程调度

实验三   模拟进程调度

实验三模拟进程调度一实验目的理解操作系统进程管理中进行进程调度的过程和编程方法,掌握先来先服务调度算法和最高优先数优先的调度算法,创建进程控制块PCB。

理解进程的状态及变化,动态显示每个进程的当前状态及进程的调度情况二实验要求编写一个允许多个进程并发执行的进程调度程序。

1)进程调度算法:进程的调度采用最高优先数优先的调度算法和先来先服务调度算法相结合的算法,并且采用动态优先数策略,选择进程占用处理器后该进程仅能使用一个时间片,运行完后优先数减1。

2)每个进程有一个进程控制块(PCB)表示。

进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等.3)进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。

进程的到达时间为输入进程的时间。

4)进程的运行时间以时间片为单位进行计算。

5)每个进程的状态可以是就绪W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。

.6)就绪进程获得CPU后都只能运行一个时间片。

用已占用CPU时间加1来表示。

7)如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。

8)每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查。

重复以上过程,直到所要进程都完成为止三概要设计进程控制块:描述进程的状态信息,用结构体定义typedef struct process{ char name[10]; //进程名int priority; //优先数Time ReachTime; //到达时间Time NeedTime; //需要运行时间Time UsedTime; //已用时间char state; //进程状态}PCB; //进程控制块图1.进程调度模拟程序模块图算法思想:定义结构体PCB描述进程的进程控制块,定义数组PCB pcb[Max]存放进程。

单处理器系统的进程调度

单处理器系统的进程调度

一.一、单处理器系统的进程调度1.实验目的在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。

当就绪进程个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。

本实验模拟在单处理器情况下的处理器调度,帮助学生加深了解处理器调度的工作。

2.实验内容与要求(1)设计多个进程并发执行的模拟调度程序,每个程序由一个PCB表示。

(2)模拟调度程序可任选两种调度算法之一实现。

(3)程序执行中应能在屏幕上显示出各进程的状态变化,以便于观察调度的整个过程。

3.实验说明设计一个按优先数调度算法实现处理器调度的程序。

(1) 假定系统有五个进程,每一个进程用一个进程控制块PCB来代表,进程控制块的格式为:其中,进程名——作为进程的标识,假设五个进程的进程名分别为P1,P2,P3,P4,P5。

指针——按优先数的大小把五个进程连成队列,用指针指出下一个进程的进程控制块的首地址,最后一个进程中的指针为“0”。

要求运行时间——假设进程需要运行的单位时间数。

优先数——赋予进程的优先数,调度时总是选取优先数大的进程先执行。

状态——可假设有两种状态,“就绪”状态和“结束”状态。

五个进程的初始状态都为“就绪”,用“R”表示,当一个进程运行结束后,它的状态为“结束”,用“E”表示。

(2) 在每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“优先数”和“要求运行时间”。

(3) 为了调度方便,把五个进程按给定的优先数从大到小连成队列。

用一单元指出队首进程,用指针指出队列的连接情况。

例:队首标志K2K 1K2K3K4 K5PCB1 PCB2 PCB3 PCB4 PCB5(4) 处理器调度总是选队首进程运行。

采用动态改变优先数的办法,进程每运行一次优先数就减“1”。

由于本实验是模拟处理器调度,所以,对被选中的进程并不实际的启动运行,而是执行:优先数-1要求运行时间-1来模拟进程的一次运行。

提醒注意的是:在实际的系统中,当一个进程被选中运行时,必须恢复进程的现场,让它占有处理器运行,直到出现等待事件或运行结束。

实验一、进程调度实验报告

实验一、进程调度实验报告

实验一、进程调度实验报告一、实验目的进程调度是操作系统中的核心功能之一,其目的是合理地分配 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分析:先来先服务调度算法简单直观,但对于短作业可能会造成较长的等待时间,导致平均等待时间和平均周转时间较长。

进程调度 实验报告

进程调度 实验报告
2轮转法图三流程图产生n个进程对每个进程用随机数产生进程的轮转时间片数及进程所需的时间片数已占用cpu的时间片数置为0按进程产生的先后次序拉成就绪队列链链首进程投入运行时间片到进程所需时间片数减1已占用cpu时间片数加1输出各进程的运行情况进程所需时间片数0
实验一进程调度实验报告
一、实验目的
多道程序设计中,经常是若干个进程同时处于就绪状态,必须依照某种策略来决定那个进程优先占有处理机。因而引起进程调度。本实验模拟在单处理机情况下的处理机调度问题,加深对进程调度的理解。
{
int num; //进程号
int attime,servtime; //进程到达时间,服务时间
process *next;
};
struct process*creatlist(int); //新建一个链表
void insert(struct process *first,struct process *s); //插入一个节点(尾插法)
process1 *next;
};
/*******************优先权调度算法所需函数声明*****************************************************/
struct process1*creatlist1(); //新建链表(就绪队列)
void insert1(struct process1 *first,struct process1 *s); //增加一个进程或将一个进程查入到队列中
void del1(struct process1 *first,struct process1 *s); //删除(撤销)一个进程
void print1(struct process1 *first); //打印函数

单处理器系统的进程调度

单处理器系统的进程调度

实验三进程调度模拟程序1. 目的和要求1.1. 实验目的用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解。

1.2. 实验要求1.2.1例题:设计一个有N个进程并发执行的进程调度模拟程序。

进程调度算法:采用最高优先级优先的调度算法(即把处理机分配给优先级最高的进程)和先来先服务(若优先级相同)算法。

(1). 每个进程有一个进程控制块(PCB)表示。

进程控制块包含如下信息:进程名、优先级、到达时间、需要运行时间、已用CPU时间、进程状态等等。

(2). 进程的优先级及需要的运行时间可以事先人为地指定,进程的运行时间以时间片为单位进行计算。

(3). 每个进程的状态可以是就绪r(ready)、运行R(Running)、或完成F (Finished)三种状态之一。

(4). 就绪进程获得CPU后都只能运行一个时间片。

用已占用CPU时间加1来表示。

(5). 如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待调度。

(6). 每进行一次调度程序都打印一次运行进程、就绪队列中各个进程的PCB,以便进行检查。

(7). 重复以上过程,直到所要进程都完成为止。

思考:作业调度与进程调度的不同?1.2.2实验题A:编写并调试一个模拟的进程调度程序,采用“最高优先数优先”调度算法对N(N不小于5)个进程进行调度。

“最高优先级优先”调度算法的基本思想是把CPU分配给就绪队列中优先数最高的进程。

(1). 静态优先数是在创建进程时确定的,并在整个进程运行期间不再改变。

(2). 动态优先数是指进程的优先数在创建进程时可以给定一个初始值,并且可以按一定规则修改优先数。

例如:在进程获得一次CPU后就将其优先数减少1,并且进程等待的时间超过某一时限(2个时间片时间)时增加其优先数等。

单处理器系统的进程调度

单处理器系统的进程调度

2017-2018学年第一学期电信学院计算机系实验报告课程名称:操作系统实验名称:单处理器系统的进程调度班级:计学号:201506姓名:成绩:一、实验目的1. 加深对进程概念的理解,明确进程和程序的区别。

2. 深入了解系统如何组织进程、创建进程。

3. 进一步认识如何实现处理器调度。

二、实验内容编写程序完成单处理机系统中的进程调度,要求采用时间片轮转调度算法。

实验具体包括:首先确定进程控制块的内容,进程控制块的组成方式;然后完成进程创建原语和进程调度原语;最后编写主函数对所做工作进行测试。

三、数据结构1.进程控制块结构定义如下:struct pcb{int name; //进程标识符int status; //进程状态int ax, bx, cx,dx; //进程现场信息,通用寄存器内容int pc; //进程现场信息,程序计数器内容int psw; //进程现场信息,进程状态字寄存器内容int next; //下一个进程控制块的位置}2. 运行进程的进程块指针,就绪队列指针和空闲进程控制块队列指针定义如下:Int run; //定义指针正在运行进程的进程控制块的指针Struct{Int head;Int tail;}Ready; //定义指针就绪队列的头指针,head和尾指针tailInt pfree; //定义指向空闲进程控制块队列的指针四、算法流程进程创建是一个原语,因此在实验中应该用一个函数实现,进程创建的过程应该包括:1.申请进程控制块:进程控制块的数量是有限的,如果没有空闲进程控制块,则进程不能创建,如果申请成功才可以执行第②步;2.申请资源:除了进程控制块外,还需要有必要的资源才能创建进程,如果申请资源不成功,则不能创建进程,并且归还已申请的进程控制块;如果申请成功,则执行第三步,实验无法申请资源,所以模拟程序忽略了申请资源这一步;3.填写进程控制块:将该进程信息写入进程控制块内,实验中只有进程标识符、进程状态可以填写,每个进程现场信息中的寄存器内容由于没有具体数据而使用进程(模拟进程创建时,需输入进程标识符字,进程标识符本应系统建立,并且是惟一的,输入时注意不要冲突),刚刚创建的进程应该为就绪态,然后转去执行第四步;4.挂入就绪队列:如果原来就绪队列不为空,则将该进程控制块挂入就绪队列尾部,并修改就绪队列尾部指针;如果原来就绪队列为空,则将就绪队列的头指针、尾指针均指向该进程控制块,进程创建完成。

实验二--单处理器系统的进程调度

实验二--单处理器系统的进程调度

实验二–单处理器系统的进程调度
简介
在操作系统中,进程调度是非常重要的一项工作。

进程调度负责将CPU分配
给各个进程,使得每个进程都能够有机会占用CPU资源。

在单处理器系统中,CPU只有一个,因此进程调度是非常重要的。

本次实验将会探究单处理器系统的进程调度,了解各种进程调度算法的实现和
比较,利用模拟操作系统的实验平台进行实验。

实验目的
1.了解进程调度的基本概念和实现方法;
2.学习多种进程调度算法,并比较其优缺点;
3.熟悉模拟操作系统的实验环境,学习如何将算法实现到具体的系统中。

实验内容
进程调度的基本概念
进程调度是指将CPU资源分配给各个进程的过程。

在单处理器系统中,当有
多个进程需要使用CPU时,操作系统需要进行进程调度,使得每个进程都能够得
到CPU资源。

在进程调度中,需要考虑各个进程的优先级、进程的状态和进程的等待时间等
因素。

根据不同的调度算法,可以根据这些因素来确定哪个进程应该先占用CPU。

进程调度算法比较
常见的进程调度算法包括:
1.先来先服务算法(FCFS)
2.短作业优先算法(SJF)
3.优先级调度算法
4.时间片轮转算法(RR)
下面将对这些算法进行比较和介绍。

先来先服务算法(FCFS)
先来先服务算法是最简单的一种进程调度算法。

该算法将按照进程的到达时间
的先后顺序进行调度,先到达的进程先得到CPU资源。

这种算法的优点是实现简单,适用于短作业和计算密集型进程。

缺点是无法充分利用CPU资源,导致长作业需要等待较长时间才能被调度,容易产生。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验三单处理器系统的进程调度(模拟算法)1.实验目的加深对进程概念的理解,明确进程和程序的区别;深入了解系统如何组织进程、创建进程;进一步认识如何实现处理器调度。

2.实验预备知识进程的概念;进程的组织方式;进程的创建;进程的调度。

3.实验内容编写程序完成单处理机系统中的进程调度,要求采用时间片轮转调度算法。

实验具体包括:首先确定进程控制块的内容,进程控制块的组成方式;然后完成进程创建原语和进程调度原语;最后编写主函数对所作工作进程测试。

4.提示与讲解这个实验主要要考虑三个问题:如何组织进程、如何创建进程和如何实现处理器调度。

考虑如何组织进程,首先就要设定进程控制块的内容。

进程控制块PCB记录各个进程执行时的情况。

不同的操作系统,进程控制块记录的信息内容不一样。

操作系统功能越强,软件也越庞大,进程控制块记录的内容也就越多。

这里的实验只使用了必不可少的信息。

一般操作系统中,无论进程控制块中信息量多少,信息都可以大致分为以下四类:①标识信息每个进程都要有一个惟一的标识符,用来标识进程的存在和区别于其他进程。

这个标识符是必不可少的,可以用符号或编号实现,它必须是操作系统分配的。

在后面给出的参考程序中,采用编号方式,也就是为每个进程依次分配一个不相同的正整数。

②说明信息用于记录进程的基本情况,例如进程的状态、等待原因、进程程序存放位置、进程数据存放位置等等。

实验中,因为进程没有数据和程序,仅使用进程控制块模拟进程,所以这部分内容仅包括进程状态。

③现场信息现场信息记录各个寄存器的内容。

当进程由于某种原因让出处理器时,需要将现场信息记录在进程控制块中,当进行进程调度时,从选中进程的进程控制块中读取现场信息进行现场恢复。

现场信息就是处理器的相关寄存器内容,包括通用寄存器、程序计数器和程序状态字寄存器等。

在实验中,可选取几个寄存器作为代表。

用大写的全局变量AX、BX、CX、DX模拟通用寄存器、大写的全局变量PC模拟程序计数器、大写的全局变量PSW模拟程序状态字寄存器。

④管理信息管理信息记录进程管理和调度的信息。

例如进程优先数、进程队列指针等。

实验中,仅包括队列指针。

因此可将进程控制块结构定义如下:struct pcb{int name;int status;int ax, bx, cx,dx;int pc;int psw;int next;}确定进程控制块内容后,要考虑的就是如何将进程控制块组织在一起。

多道程序设计系统中,往往同时创建多个进程。

在单处理器的情况下,每次只能有一个进程处于运行态,其他的进程处于就绪状态或等待状态。

为了便于管理,通常把处于相同状态的进程的进程控制块链接在一起。

单处理器系统中,正在运行的进程只有一个。

因此,单处理器系统中进程控制块分成一个正在运行进程的进程控制块、就绪进程的进程控制块组织成的就绪队列和等待进程的进程控制块组成的等待队列。

由于实验模拟的是进程调度,没有对等待队列的操作,所以实验中只有一个指向正在运行进程的进程控制块指针和一个就绪进程的进程控制块队列指针。

操作系统的实现中,系统往往在主存中划分出一个连续的专门区域存放系统的进程控制块,实验中应该用数组模拟这个专门的进程控制块区域,定义如下:#define n 10struct pcb pcbarea[n];这样,进程控制块的链表实际上是数据结构中使用的静态链表。

进程控制块的链接方式可以采用单向和双向链表,实验中,进程控制块队列采用单向不循环静态链表。

为了管理空闲进程控制块,还应该将空闲控制块链接成一个队列。

实验中采用时间片轮转调度算法,这种算法是将进程控制块按照进入就绪队列的先后次序排成队列。

关于就绪队列的操作就是从队头摘下一个进程控制块和从队尾挂入一个进程控制块。

因此为就绪队列定义两个指针,一个头指针,指向就绪队列的第一个进程控制块;一个尾指针,指向就绪队列的最后一个进程控制块。

实验中指向运行进程的进程控制块指针、就绪队列指针和空闲进程控制块队列指针定义如下:int run;struct{int head;int tail;}ready;int pfree;以上是如何组织进程,下面考虑如何创建进程。

进程创建是一个原语,因此在实验中应该用一个函数实现,进程创建的过程应该包括:①申请进程控制块:进程控制块的数量是有限的,如果没有空闲进程控制块,则进程不能创建,如果申请成功才可以执行第②步;②申请资源:除了进程控制块外,还需要有必要的资源才能创建进程,如果申请资源不成功,则不能创建进程,并且归还已申请的进程控制块;如果申请成功,则执行第三步,实验无法申请资源,所以模拟程序忽略了申请资源这一步;③填写进程控制块:将该进程信息写入进程控制块内,实验中只有进程标识符、进程状态可以填写,每个进程现场信息中的寄存器内容由于没有具体数据而使用进程(模拟进程创建时,需输入进程标识符字,进程标识符本应系统建立,并且是惟一的,输入时注意不要冲突),刚刚创建的进程应该为就绪态,然后转去执行第四步;④挂入就绪队列:如果原来就绪队列不为空,则将该进程控制块挂入就绪队列尾部,并修改就绪队列尾部指针;如果原来就绪队列为空,则将就绪队列的头指针、尾指针均指向该进程控制块,进程创建完成。

进程创建流程图如图2.2所示。

多道程序设计的系统中,处于就绪态的进程往往是多个,它们都要求占用处理器,可是单处理器系统的处理器只有一个,进程调度就是解决这个处理器竞争问题的。

进程调度的任务就是按照某种算法从就绪进程队列中选择一个进程,让它占有处理器。

因此进程调度程序就应该包括两部分,一部分是在进程就绪队列中选择一个进程,并将其进程控制块从进程就绪队列中摘下来,另一部分工作就是分配处理器给选中的进程,也就是将指向正在运行进程的进程控制块指针指向该进程的进程控制块,并将该进程的进程控制块信息写入处理器的各个寄存器中。

图2.2 进程创建流程图实验中采用时间片轮转调度算法。

时间片轮转调度算法让就绪进程按就绪的先后次序排成队列,每次总是选择就绪队列中的第一个进程占有处理器,但是规定只能使用一个“时间片”。

时间片就是规定进程一次使用处理器的最长时间。

实验中采用每个进程都使用相同的不变的时间片。

采用时间片轮转调度算法的进程调度流程图如图2.3所示。

完成上述功能后,编写主函数进行测试:首先建立一个就绪队列,手工输入信息建立几个进程;然后进行进程调度;最后将指向正在运行进程的指针指向的进程控制块的内容输出,察看结果。

图2.3 进程调度流程图5.思考题如果采用优先数调度策略实现进程调度,又该如何设计算法?附:实现代码(C语言):#include <stdio.h>#include<windows.h>#define N 10 //系统中所允许的最大进程数量#define SLOT 5 //时间片大小//进程状态枚举typedef enum{Running, //运行状态Aready, //就绪状态Blocking //阻塞状态} ProStatus;//进程控制块typedef struct{int name; //进程标识符ProStatus status; //进程状态int ax,bx,cx,dx; //通用寄存器int pc; //程序计数器寄存器int psw; //程序状态字寄存器int next; //指向下一个进程的指针} PCB;//就绪队列指针typedef struct{int head; //头指针int tail; //尾指针} Ready;//模拟寄存器int PSW,AX,BX,CX,DX,PC,TIME;//PCB的静态链表PCB pcbArea[N]; //模拟PCB区域的数组int run; //运行状态程序的指针Ready ready; //就绪队列指针int pfree; //空闲队列的指针//初始化运行状态进程指针void InitRun(){run=-1;}//初始化就绪状态队列void InitReady(){ready.head=ready.tail=-1;}//初始化空闲队列void InitFree(){int temp;for(temp=0;temp<N-1;temp++){pcbArea[temp].next=temp+1;}pcbArea[temp].next=-1;pfree=0;}//就绪队列出队int PopReady() //返回结点在PCB区域数组的编号{int temp;if(ready.head==-1){printf("就绪队列为空,不能出队。

\n");return -1;}temp=ready.head;ready.head=pcbArea[temp].next;if(ready.head==-1)ready.tail=-1;pcbArea[temp].next=-1;return temp;}//空闲队列出队int PopFree() //返回结点在PCB区域数组的编号{int temp;if(pfree==-1){printf("空闲队列为空,不能出队。

\n");return -1;}temp=pfree;pfree=pcbArea[temp].next;pcbArea[temp].next=-1;return temp;}//就绪队列入队void PushReady(int x) //x为入队结点的编号{int temp;if(ready.head==-1){ready.head=x;ready.tail=x;}else{temp=ready.tail;ready.tail=x;pcbArea[temp].next=x;}pcbArea[ready.tail].next=-1;}//创建PCBvoid CreatePCB(int x,PCB pcb) //x为要创建PCB在PCB区域数组的编号{pcbArea[x].ax=pcb.ax;pcbArea[x].bx=pcb.bx;pcbArea[x].cx=pcb.cx;pcbArea[x].dx=pcb.dx;pcbArea[x].name=;pcbArea[x].next=-1;pcbArea[x].pc=pcb.pc;pcbArea[x].psw=pcb.psw;pcbArea[x].status=pcb.status;}//创建进程函数void Create(PCB pcb){int temp;if(pfree==-1){printf("空闲队列为空,不能创建进程。

\n");return;}temp=PopFree();pcb.status=Aready;CreatePCB(temp,pcb);PushReady(temp);}//进程调度函数void Schedule(){int temp;if(ready.head==-1){printf("系统内没有进程可以调度。

相关文档
最新文档