实验一 单处理器系统进程调度(正确)
单处理器系统的进程调度

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

处理器调度一、实验内容选择一个调度算法,实现处理器调度。
二、实验目的在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。
当就绪状态进程个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。
本实验模拟在单处理器情况下处理器调度,帮助学生加深了解处理器调度的工作。
三、实验题目设计一个按优先数调度算法实现处理器调度的程序提示:(1)假定系统有五个进程,每一个进程用一个进程控制块PCB来代表。
进程控制块的格式为:其中,进程名----作为进程的标识,假设五个进程的进程名分别是R, P2, P3,P4,R。
指针—按优先数的大小把五个进程连成队列,用指针指出下一个进程的进程控制块首地址,最后一个进程中的指针为“ 0”。
要求运行时间-- 假设进程需要运行的单位时间数。
优先数-赋予进程的优先数,调度时总是选取优先数大的进程先执行。
状态-可假设有两种状态,“就绪”状态和“结束“状态,五个进程的初始状态都为“就绪“状态,用“ R”表示,当一个进程运行结束后,它的状态变为“结束”,用“ E”表示。
(2)在每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“优先数”和“要求运行时间”。
(3)为了调度方便,把五个进程按给定的优先数从大到小连成队列,用一单元指出队首进程,用指针指出队列的连接情况。
例:队首标志(4)处理器调度总是选队首进程运行。
采用动态改变优先数的办法,进程每运行一次优先数就减“ 1”。
由于本实验是模拟处理器调度,所以,对被选中的进程并不实际的启动运行,而是执行:优先数- 1 要求运行时间-1来模拟进程的一次运行提醒注意的是:在实际的系统中,当一个进程被选中运行时,必须恢复进程的现场,它占有处理器运行,直到出现等待事件或运行结束。
在这里省去了这些工作。
(5)进程运行一次后,若要求运行时间工0,则再将它加入队列(按优先数大小插入,且置队首标志);若要求运行时间=0,则把它的状态修改为“结束”(),且退出队列。
实验一——单处理器系统的进程调度

实验一——单处理器系统的进程调度实验一:进程的建立及调度1.实验目的:加深对进程概念的理解,熟悉PCB的组织,深入了解创建进程的一般过程,掌握用队列组织进程的方法,掌握进程调度算法。
2.实验内容编程实现创建原语,形成就绪队列,模拟实现进程的调度。
具体内容包括:1)、确定进程控制块的内容,用链表组织进程控制块;2)、完成进程创建原语和进程调度原语;3)、要求采用时间片轮转调度算法;4)、编写主函数对所做工作进程测试。
3、实验具体内容和步骤的说明这个实验主要考虑三个问题:如何组织进程、如何创建进程和如何实现处理器调度。
1)、进程的组织:首先就要设定进程控制块的内容。
进程控制块PCB记录各个进程执行时的情况。
不同的操作系统,进程控制块所记录的信息内容不一样。
操作系统功能越强,软件也越庞大,进程控制块所记录的内容也就越多。
本次实验只使用必不可少的信息。
一般操作系统中,无论进程控制块中信息量多少,信息都可以大致分为以下四类:①标识信息每个进程都要有一个惟一的标识符,用来标识进程的存在和区别于其他进程。
这个标识符是必不可少的,可以用符号或编号实现,它必须是操作系统分配的。
本实验中要求,采用编号方式,也就是为每个进程依次分配一个不相同的正整数。
②说明信息用于记录进程的基本情况,例如进程的状态、等待原因、进程程序存放位置、进程数据存放位置等等。
本模拟实验中,因为进程没有数据和程序,仅使用进程控制块模拟进程,所以这部分内容仅包括进程状态。
③现场信息现场信息记录各个寄存器的内容。
当进程由于某种原因让出处理器时,需要将现场信息记录在进程控制块中,当进行进程调度时,从选中进程的进程控制块中读取现场信息进行现场恢复。
现场信息就是处理器的相关寄存器内容,包括通用寄存器、程序计数器和程序状态字寄存器等。
在实验中,可选取几个寄存器作为代表。
用大写的全局变量AX、BX、CX、DX模拟通用寄存器、大写的全局变量PC模拟程序计数器、大写的全局变量PSW模拟程序状态字寄存器。
进程调度 实验报告

一、实验目的
多道程序设计中,经常是若干个进程同时处于就绪状态,必须依照某种策略来决定那个进程优先占有处理机。因而引起进程调度。本实验模拟在单处理机情况下的处理机调度问题,加深对进程调度的理解。
二、实验内容
1.优先权法、轮转法
简化假设
1)进程为计算型的(无I/O)
2)进程状态:ready、running、finish
{
int num; //进程号
int attime,servtime; //进程到达时间,服务时间
process *next;
};
struct process*creatlist(int); //新建一个链表
void insert(struct process *first,struct process *s); //插入一个节点(尾插法)
}
}
void privilege(struct process1 *first)
{
struct process1* p,*r=first,*t;
p=first->next;
int b=0;
while (first->next)
{
r=first;
p=first->next;
cout<<"/********************"<<b<<"*****************************/"<<endl;
{
struct process1 *p,*r;
p=first->next;
r=first;
int a=1;
while (a)
实验一处理器调度实验报告

实验一处理器调度之杨若古兰创作一、实验内容选择一个调度算法,实现处理器调度.二、实验目的在采取多道程序设计的零碎中,常常有若干个进程同时处于就绪形态.当就绪形态进程个数大于处理器数时,就必须按照某种计谋来决定哪些进程优先占用途理器.本实验模拟在单处理器情况下处理器调度,帮忙先生加深了解处理器调度的工作.三、实验题目设计一个按优先数调度算法实现处理器调度的程序提示:(1)假定零碎有五个进程,每一个进程用一个进程控制块PCB 来代表.进程控制块的格式为:其中,进程名----作为进程的标识,假设五个进程的进程名分别是P1,P2,P3,P4,P5.指针----按优先数的大小把五个进程连成队列,用指针指出下一个进程的进程控制块首地址,最初一个进程中的指针为“0”.请求运转时间----假设进程须要运转的单位时间数.优先数----赋予进程的优先数,调度时老是拔取优先数大的进程先履行.形态----可假设有两种形态,“就绪”形态和“结束“形态,五个进程的初始形态都为“就绪“形态,用“R”暗示,当一个进程运转结束后,它的形态变成“结束”,用“E”暗示.(2)在每次运转你所设计的处理器调度程序之前,为每个进程任意确定它的“优先数”和“请求运转时间”.(3)为了调度方便,把五个进程按给定的优先数从大到小连成队列,用一单元指出队首进程,用指针指出队列的连接情况.例:队首标记(4)处理器调度老是选队首进程运转.采取动态改变优先数的法子,进程每运转一次优先数就减“1”.因为本实验是模拟处理器调度,所以,对被选中的进程其实不实际的启动运转,而是履行:优先数-1请求运转时间-1来模拟进程的一次运转.提醒留意的是:在实际的零碎中,当一个进程被选中运转时,必须恢复进程的现场,它据有处理器运转,直到出现等待事件或运转结束.在这里省去了这些工作.(5)进程运转一次后,若请求运转时间≠0,则再将它加入队列(按优先数大小拔出,且置队首标记);若请求运转时间=0,则把它的形态点窜为“结束”(),且退出队列.(6)若“就绪”形态的进程队列不为空,则反复上面(4)和(5)的步调,直到所有进程都成为“结束”形态.(7)在所设计的称序中应有显示或打印语句,能显示或打印每次被选中进程的进程名以及运转一次后进称对列的变更.(8)为五个进程任意确定一组“优先数”和“请求运转时间”,启动所设计的处理器调度程序,显示或打印逐次被选中进程的进程名和进程控制块的动态变更过程.四、程序中使用的数据结构及符号说明:#define num 5//假定零碎中进程个数为5struct PCB{char ID;//进程名int runtime;//请求运转时间int pri;//优先数char state; //形态,R-就绪,F-结束};struct PCB pcblist[num];//定义进程控制块数组五、流程图:(1)(2)子程序init()(3) 子程序max_pri_process()流程图:(4)子程序show()流程图:(5)子程序run()流程图://按优先数调度算法实现处理器调度的程序#include "stdio.h"#include "string.h"#define num 5//假定零碎中进程个数为5struct PCB{char ID;//进程名int runtime;//请求运转时间int pri;//优先数char state; //形态,R-就绪,F-结束};struct PCB pcblist[num];//定义进程控制块数组void init()//PCB初始化子程序{int i;for(i=0;i<num;i++){printf("PCB[%d]:ID pri runtime \n",i+1);//为每个进程任意指定pri和runtimescanf("%s%d%d",&pcblist[i].ID,&pcblist[i].pri,&pcblist[i].runtime );pcblist[i].state='R';//进程初始形态均为就绪getchar();//接收回车符}}int max_pri_process()//确定最大优先级进程子程序{int max=-100;//max为最大优先数,初始化为-100int i;int key;for(i=0;i<num;i++){if(pcblist[i].state=='r')//r为辅助形态标记,暗示正在运转return -1;//返回-1elseif(max<pcblist[i].pri&&pcblist[i].state=='R')//从就绪进程中拔取优先数最大的进程{max=pcblist[i].pri;//max存放每次轮回中的最大优先数key=i;//将进程号赋给key}}if(pcblist[key].state=='F')//具有最大优先数的进程若已运转终了return -1;//则返回-1else//否则return key;//将key作为返回值返回}void show()//显示子程序{int i;printf("\n ID pri runtime state\n");printf("-------------------------------------------------\n");for(i=0;i<num;i++)//顺次显示每个进程的名、优先数、请求运转时间和形态{printf("%s%6d%8d %s\n",&pcblist[i].ID,pcblist[i].pri,pcblist[ i].runtime,&pcblist[i].state);}printf(" press any key to continue...\n");}void run()//进程运转子程序{int i,j;int t=0;//t为运转次数for(j=0;j<num;j++){t+=pcblist[j].runtime;}//运转次数即为各个进程运转时间之和printf("\nbefore run,the conditon is:\n");show(); //调用show()子程序显示运转前PCB的情况getchar();//等待输入回车符for(j=0;j<t;j++){while(max_pri_process()!=-1)//具有最大优先数的进程没有运转完,让其运转{pcblist[max_pri_process()].state='r';//将其形态置为r,暗示其正在运转}for(i=0;i<num;i++){if(pcblist[i].state=='r'){ pcblist[i].pri-=1;//将当前运转进程的优先数减1 pcblist[i].runtime--;//请求运转时间减1{if(pcblist[i].runtime==0)pcblist[i].state='F';//运转完则将该进程形态置为结束elsepcblist[i].state='R';//未运转完将其形态置为就绪}show();//显示每次运转后各PCB的情况getchar();//等待回车进入下一次运转} } }}void main()//按动态优先数调度主程序{init();//初始化各个进程PCBrun();//进程调度模拟}七、实验总结本次实验通过课本处理器调度的进程的初步认识和实验按优先数调度算法实现处理器调度的实现,了解到进程与进程控制块之间的联系,进程运转过程中形态和已运转时间的判断和计算,选中运转的进程名和选中进程运转后的各进程控制块形态.。
实验一单处理器调度算法的实现

实验一单处理器调度算法的实现班级:计算机04-1班学号: 04034040112姓名:汀芷约成绩:___ ________日期:_ 2006-11-02实验一单处理器调度算法的实现一、实验目的在多道程序或多任务系统中,系统同时处于就绪态的进程有若干个。
为了使系统中的各进程能有条不紊地运行,必须选择某种调度策略,以选择占用处理机。
要求学生设计一个模拟单处理机调度的算法,以巩固和加深处理机调度的概念。
二、实验内容设计一个按时间片轮转法调度的算法。
提示:1、假设系统有5个进程,每个进程用一个进程控制块PCB来代表。
PCB 的格式如图所示。
其中,进程名即是进程标识。
链接指针:指出下一个到达进程的进程控制块首地址。
按照进程到达的顺序排队。
系统设置一个队头和队尾指针分别指向第一个和最后一个进程。
新生成的进程放队尾。
2、为每个进程任意确定一个要求运行时间和到达时间。
3、按照进程到达的先后顺序排成一个循环队列。
再设一个队首指针指向第一个到达进程的首地址。
4、执行处理机调度时,开始选择队首的第一个进程运行。
另外再设一个当前运行进程指针,指向当前正运行的进程。
5、由于本实验是模拟实验,所以对被选中进程并不实际启动运行,而是执行:一是估计运行时间减1;二是输出当前运行进程的名字。
用这两个操作来模拟进程的一次执行。
6、进程运行一次后,以后的调度则将当前指针依次下移一个位置,指向下一个进程,即调整当前运行指针指向该进程的链接指针所指进程,以指示应运行进程。
同时还应该判断该进程的剩余运行是否为0。
若不为0,则等待下一轮的运行;若该进程的剩余时间为0,则将该进程的状态置为C,并退出循环队列。
7、若就绪队列不空,则重复上述的(5)和(6)步骤直到所有进程都运行为止。
8、在所设计的调度程序中,应包含显示或打印语句。
以便显示或打印每次选中进程的名称及运行一次后队列的变化情况。
三、实验说明1、程序中使用的数据结构及符号说明:数据结构:数组data[][]符号说明:每个进程的状态是就绪 W(Wait)、运行R(Run)、或完成C(Complete)三种状态之一。
实验一 处理机调度实验报告

实验一处理机调度实验报告一、实验目的处理机调度是操作系统中的一个重要组成部分,其目的是合理地分配处理机资源,以提高系统的性能和效率。
本次实验的主要目的是通过模拟处理机调度算法,深入理解不同调度算法的工作原理和性能特点,并能够对它们进行比较和分析。
二、实验环境本次实验使用了以下软件和工具:1、操作系统:Windows 102、编程语言:Python3、开发环境:PyCharm三、实验内容1、先来先服务(FCFS)调度算法先来先服务调度算法按照作业或进程到达的先后顺序进行调度。
即先到达的作业或进程先得到处理机的服务。
2、短作业优先(SJF)调度算法短作业优先调度算法优先调度运行时间短的作业或进程。
在实现过程中,需要对作业或进程的运行时间进行预测或已知。
3、高响应比优先(HRRN)调度算法高响应比优先调度算法综合考虑作业或进程的等待时间和运行时间。
响应比的计算公式为:响应比=(等待时间+要求服务时间)/要求服务时间。
4、时间片轮转(RR)调度算法时间片轮转调度算法将处理机的时间分成固定大小的时间片,每个作业或进程在一个时间片内运行,当时间片用完后,切换到下一个作业或进程。
四、实验步骤1、设计数据结构为了表示作业或进程,设计了一个包含作业或进程 ID、到达时间、运行时间和等待时间等属性的数据结构。
2、实现调度算法分别实现了上述四种调度算法。
在实现过程中,根据算法的特点进行相应的处理和计算。
3、模拟调度过程创建一组作业或进程,并按照不同的调度算法进行调度。
在调度过程中,更新作业或进程的状态和相关时间参数。
4、计算性能指标计算了平均周转时间和平均带权周转时间等性能指标,用于评估不同调度算法的性能。
五、实验结果与分析1、先来先服务(FCFS)调度算法平均周转时间:通过计算所有作业或进程的周转时间之和除以作业或进程的数量,得到平均周转时间。
在 FCFS 算法中,由于按照到达顺序进行调度,可能会导致长作业或进程长时间占用处理机,从而使平均周转时间较长。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验一单处理器系统进程调度
一、实验目的
1.加深对进程概念的理解,明确进程和程序的区别。
2.深入了解系统如何组织进程、创建进程。
3.进一步认识如何实现处理器调度。
二、实验预备知识
1.进程的概念。
2.进程的组织方式。
3.进程的创建。
4.进程的调度。
三、实验内容
编写程序完成单处理机系统中的进程调度,要求采取用时间片轮转调度算法。
试验具体包括:首先确定进程控制块的内容,进程控制块的组成方式;然后完成进程创建、调度原语;最后编写主函数对所做工作进行测试。
四、提示
这个实验主要要考虑三个问题:如何组织进程、如何创建进程和如何实现处理器调度。
考虑如何组织进程,首先就要设定进程控制块的内容。
进程控制块PCB,记录各个进程执时的情况。
不同的操作系统,进程控制块记录的信息内容不_样。
操作系统功能越强,软件也越庞大,进程控制块记录的内容也就越多。
这里的实验只使用了必不可少~信息。
一般操作系统中,无论进程控制块中信息量多少,信息都可以大致分为以下四类:
(1)标识信息
每个进程都要有一个惟一的标识符,用来标识进程的存在和区别于其他进程。
这个标识符是必不可少的,可以用符号或编号实现,它必须是操作系统分配的。
在后面给出的参考程序中,采用编号方式,也就是为每个进程依次分配一个不相同的正整数。
(2)说明信息
用于记录进程的基本情况,例如进程的状态、等待原因、进程程序存放位置、进程数据存放位置等等。
实验中,因为进程没有数据和程序,仅使用进程控制块模拟进程,。
所以这部分内容仅包括进程状态。
{int head;
int tail;
}ready;//定义指向就绪队列的头指针head和尾指针tail
int pfree;//定义指向空闲进程控制块队列的指针
进程创建是一个原语,因此在实验中应该用一个函数实现,进程创建的过程应该包括:
(1)申请进程控制块:进程控制块的数量是有限的,如果没有空闲进程控制块,则进程
不能创建,如果申请成功才可以执行第二步;
(2)申请资源:除了进程控制块外,还需要有必要的资源才能创建进程,如果申请资
源不成功,则不能创建进程,并且归还已申请的进程控制块:如果申请成功,则执行第三步,实验无法申请资源,所以模拟进程忽略了申请资源这一步
(3)填写进程控制块:将该进程信息写入进程控制块内,实验中只有进程标识符、进
程状态可以填写,每个进程现场信息中的寄存器内容由于没有具体数据而使用进程(模拟进程创建时,需输入进程标识符字,进程标识符本应系统建立,并且是惟一一的,输入时注
意不要冲突),刚刚创建的进程应该为就绪态,然后转去执行第四步;
(4)挂人就绪队列:如果原来就绪队列不为空,则将该进程控制块挂入就绪队列尾部,
并修改就绪队列尾部指针:如果原来就绪队列为空,则将就绪队列的头指针、尾指针均指向该进程控制块,进程创建完成。
多道程序设计的系统中,处于就绪的进程让律是多个,它们都要求占用处理器,可单处理器系统的处理器只有一个,进程调度就是解决这个处理器竞争问题的一进程调度的任务就是按照某种算法从就绪进程队列中选择一个进程,让它占自处理器。
因此进程调度程序就应该包括两部分.一部分在进程就绪队列中选择一个进程,并将其进程控制块从进程就绪队列中摘下来,另部分工作就是分配处理器给选中的进程,也就是将指向正在运行进程的进程控制块指针指向该进程的进程控制块,并将该进程的进程控制块信息写入处理器的各个寄存器中。
实验中采用时间片轮转调度算法。
时间片轮转调度算法让就绪进程按就绪的先后次宁排成队,每次总是选择就绪队列中的第一个进程占有处理器,但是规定只能使用一个“时间片”。
时间片就是规定进程一次使用处理器的最长时间。
实验中采用每个进程都使用相同的不变的时间片。
五、参考程序
#include“stdiO.h”//用running表示进程处于运行态
#define running 1 //用aready表示进程处于就绪态
#define aready 2 //用blocking表示进程处于等待态
#define blocking 3 //用sometime表示时间片大小
#define sometime 5 //假定系统允许进程个数为n
#define n 10
Struct
{int name; //进程标识符
int status; //进程状态
int ax,bx,cx,dx; //进程现场信息,通用寄存器内容
int pc; //进程现场信息,程序计数器内容
int psw;//进程现场信息,程序状态字寄存器内容
int next; //下一个进程控制块的位置
}pcbarea[n]; //模拟进程控制块区域的数组
int psw,ax,bx,cx,dx,pc,time;//模拟寄存器
int run; //定义指向正在运行进程的进程控制块的指针 struct
{int head;
int tai1;
}ready; //定义就绪队列的头指针head和尾指针tail// int Pfree; //定义指向空闲进程控制块队列的指针
sheduling() //进程调度函数
{int i;
if (ready.head==-1) //空闲进程控制块队列为空,退出
{print~(“无就绪进程\n”);
return;
}
i=ready.head; //就绪队列头指针赋给i
ready.head=pcbarea[ready.head].next;//就绪队列头指针后移
if(ready.head==-1) ready.tail=-1; //就绪队列为空,修正尾指针
pcbarea[i].status=running; //修改进程控制块状态
TIME=sometime; //设置相对时钟寄存器//恢复该进程现场信息
AX=pcbarea[run].ax;
BX=pcbarea[run].bx;
CX=pcbarea[run].cx;
DX=pcbarea[run].dx;
PC=pcbarea[run].pc;
PSW=pcbarea[run].psw;
run=i; //修改指向运行进程的指针
}//进程调度函数结束
create(int X) //创建进程
{int i;
if(pfree==-1)
{printf(“无空闲进程控制块\n”);
return;
}
i=pfree; //空闲进程控制块队列为空进程创建失败\n--); // pfree=pcbarea[pfree].next; //取空闲进程控制块队列的第一个
//填写该进程控制块内容://free启移
pcbarea[i].n ame=x;
pcbarea[i].status=areadv;
pcbarea[i].ax=x;
pcbarea[i].bx=x;
pcbarea[i].cx=x;
pcbarea[i].dx=x;
pcbarea[i].pc=x;
pcbarea[i].psw=x;
if(ready.head!=-1) //就绪队列不空时,挂入就绪队列方式
{pcbarea[ready.tail].next=i,
ready.tail=i;
pcbarea[ready.tail].next=-1;
}
else //就绪队列空时,挂入就绪队列方式
{ready.head=i;
ready.tail=i;
pcbarea[ready.tail].next=-1;
}
//进程创建函数结束
main()
{//系统初始化
int num,i,j;
run=ready.head=ready.tail=block=-1;
pfree=O;
for(i=O;j<n-i;j++) pcbarea[j].next=j+1,
pcbarea[n-1].next=-1;
printf("输入进程编号(避免编号的冲突,以负数输入结束,最多可以创建10):\n"); scanf(“%d”,&num);
while(num>=O)
{create(num);
scanf("%d”,&num);
sheduling();
if(run!=一1)
{printf("进程标志符进程状态寄存器内容:ax bx cx dx pc psw:\n");
printf("%8d%10d%3d%3d%3d%3d%3d%3d\n",pcbarea[run].name);
pcbarea[run].status, pcbarea[run].ax, pcbarea[run].bx, pcbarea[run].cx, pcbarea[run].dx, pcbarea[run].pc, pcbarea[run].psw);
}
}
}//main()结束。