操作系统---进程调度算法的模拟
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
if(readyQueueNum > 0){
///选择就绪队列优先级最高的进程作为CPU运行进程
cpuProcess = readyQueuePop();
}else{
///就绪队列中没有进程,改为选择阻塞队列优先级最高的进程
cpuProcess = blockQueuePop();
}
cpuProcess->cpuTime = 0; ///设置当前运行进程占用CPU时间
}
printf("\n模拟进程动态优先权调度算法结束.\n");
return 0;
(2)动态优先权调度算法流程图
(2)实验结果
①第1个时间片后:
②第2个时间片后:
③第3个时间片后:
④第4个时间片后:
⑤第5个时间片后:
⑥第6个时间片后:
⑦第7个时间片后:
⑧第8个时间片后:
⑨第9个时间片后:
⑩第10个时间片后:
⑪第11个时间片后:
⑫第12个时间片后:
⑬第13个时间片后:
⑭第14个时间片后:
⑮第15个时间片后:
⑯第16个时间片后:
⑰第17个时间片后:
⑱第18个时间片后:
⑲第19个时间片后:
⑳第20个时间片后:
(3)实验结果分析
①调度算法开始之前进程PCB信息为:
②调度算法结束之后进程PCB信息为:
③调度算法分析:
队列头可运行进程
最高优先级
最低优先级
教 师 评 价
评定项目
A
B
C
D
评定项目
A
B
C
D
算法正确
界面美观,布局合理
程序结构合理
操作熟练
语法、语义正确
解析完整
实验结果正确
文字流畅
报告规范
题解正确
其他:
评价教师签名:
年月日
pHead = initData(); ///初始化进程PCB,返回进程头指针
pro = pHead + 1; ///pro指向PCB中第一个进程
readyQueueUpdate(timeSlice,pro); ///根据进程到达时间将新建进程加入绪队列
///模拟动态优先权进程调度
while(true){
B
2
6
C
4
4
D
6
5
E
8
2
(2)每个用来标识进程的进程控制块PCB可用结构来描述,包括以下字段(用不到的字段可以不定义)。
进程标识数ID。
进程优先数PRIORITY,并规定优先数越大的进程,其优先权越高。
进程已占用CPU时间CPUTIME。
进程还需占用的CPU时间ALLTIME。当进程运行完毕时,ALLTIME变为0。
三、实验内容
(1)用C、C++、Java语言编程实现对5个进程采用动态优先权调度算法进行调度的过程。数据如下:
5个进程的到达时刻和服务时间见下表,忽略I/O以及其它开销时间,使用动态优先权算法进行调度,优先权初始值为100,请输出各个进程的完成时刻、周转时间、带权周转时间。
进程
到达时刻
服务时间
A
0
3
}///end if
///更新就绪队列和阻塞队列中的进程信息
blockQueueUpdate();
readyQueueUpdate来自百度文库timeSlice,pro);
///查看就绪队列和阻塞队列的进程信息
readyQueueWalk();
blockQueueWalk();
if(cpuBusy == 1 && readyQueueNum > 0 &&
《操作系统》
实验题目
进程调度算法模拟
一、实验目的
通过对进程调度算法的模拟,进一步理解进程的基本概念,加深对进程运行状态和进程调度过程、调度算法的理解。
二、设备与环境
(1)硬件设备:PC机一台
(2)软件环境:安装Windows操作系统或者Linux操作系统,并安装相关的程序开发环境,如C \C++\Java等编程语言环境。
进程的阻塞时间STARTBLOCK,表示当进程再运行STARTBLOCK个时间片后,进程将进入阻塞状态。
进程被阻塞的时间BLOCKTIME,表示已阻塞的进程再等待BLOCKTIME个时间片后,将转换成就绪状态。
进程状态STATE。
队列指针NEXT,用来将PCB排成队列。
(3)优先数改变的原则:
进程在就绪队列中呆一个时间片,优先数增加1。
};
typedef struct PCB_NODE PCB;
②模拟进程队列操作函数定义:
///进程入列
void queuePush(PCB *process, PCB *queueHead)
///进程出列
void queuePop(PCB *process, PCB *queueHead)
///查看队列中进程信息
此外,优先级可以由系统动态确定。例如有些进程为I/O密集型,其多数时间用来等待I/O结束。当这样的进程需要CPU时,应立即分配给它CPU,以便启动下一个I/O请求,这样就可以在另一个进程计算的同时执行I/O操作。使这类I/O密集型进程长时间等待只会造成它无谓地长时间占用内存。使I/O密集型进程获得较好服务的一种简单算法是,将其优先级设为1/f,f为该进程在上一时间片中所占的部分。如果一个在其50ms的时间片中只使用1ms的进程的优先级为50,而在阻塞之前用掉25ms的进程优先级为2,使用掉全部时间片的进程优先级为1。
这样,可以很方便地将一组进程按优先级分成若干类,并在各类之间采用优先级调度,而在各类进程的内部采用轮转调度。如下图为一个具有4类优先级的系统,其调度算法如下:只要存在优先级为第4类的可运行进程,就按照轮转法为每个进程运行一个时间片,此时不理会较低优先级的进程。若第4类进程为空,则按照轮转法运行第3类进程。若第4类和第3类均为空,则按照轮转法运行第2类进程。如果不偶尔对优先级进行调整,则低优先级进程很可能会产生饥饿现象。
cpuProcess->state = Run; ///设置当前运行进程的状态
cpuBusy = 1; ///设置CPU当前状态为忙
}///end if
timeSlice ++; ///当前时间片加1
printf("\n第%d个时间片后:\n",timeSlice);
cpuWord(cpuProcess); ///模拟CPU执行1个时间片的操作
void cpuWord(PCB *cpuProcess)
⑥主函数关键代码:
int timeSlice = 0; ///模拟CPU时间片
int cpuBusy = 0; ///模拟CPU状态
PCB *cpuProcess = NULL; ///当前CPU执行的进程
PCB *pHead,*pro; ///进程PCB头指针
cpuProcess->priority < readyMaxPriority()){
blockQueuePush(cpuProcess); ///需抢占CPU,当前执行的进程调入阻塞队列
cpuProcess = readyQueuePop(); ///从就绪队列中选择优先级最高的进程运行
}///end if
///返回就绪队列最大优先数的值
int readyMaxPriority()
///查看就绪队列中的进程信息
void readyQueueWalk()
④模拟阻塞队列操作函数定义:
///进程插入到阻塞队列
void blockQueuePush(PCB *process)
///优先数最大的进程出列
PCB * blockQueuePop()
///每个时间片更新阻塞队列中进程的信息
void blockQueueUpdate()
///查看阻塞队列中的进程信息
void blockQueueWalk()
⑤模拟动态优先权进程调度函数定义:
///初始化进程PCB数据,返回PCB头指针
PCB * initData()
///模拟CPU执行1个时间片的操作
进程每运行一个时间片,优先数减3。
(4)为了清楚地观察每个进程的调度过程,程序应将每个时间片内的进程的情况显示出来,包括正在运行的进程,处于就绪队列中的进程和处于阻塞队列中的进程。
(5)分析程序运行的结果,谈一下自己的认识。
四、实验结果及分析
(1)实验关键代码
①模拟PCB数据结构定义:
///枚举进程的状态:新建、就绪、执行、阻塞、终止
int cpuTime; ///进程已占用CPU时间
int allTime; ///进程还需占用CPU时间
int blockTime; ///进程已阻塞时间
STATE state; ///进程状态
struct PCB_NODE *prev; ///PCB前指针
struct PCB_NODE *next; ///PCB后指针
进程ID
到达时间
服务时间
结束时间
周转时间
带权周转时间
0
0
3
10
10
3.3
1
2
6
20
18
3.0
2
4
4
16
12
3.0
3
6
5
18
12
2.4
4
8
2
13
5
2.5
(4)实验心得
通过进程动态优先权调度算法的模拟,对进程的运行状态,进程PCB数据结构,进程调度算法有了更深的理解。动态优先权调度算法为了防止高优先级进程无休止地运行下去,调度程序在每个时钟滴答(即每个时钟中断)降低当前进程的优先级。如果这个动作导致该进程的优先级低于次高优先级的进程,则进行进程切换,可以避免低优先级进程长时间的饥饿等待。
if(cpuProcess->allTime == 0){ ///若当前执行进程还需CPU时间片为0
cpuProcess->state = Finish; ///设置当前进程状态为终止
free(cpuProcess); ///释放该进程的PCB内存空间
cpuBusy = 0; ///CPU状态设置为空闲
enum STATE_PROCESS {New,Ready,Run,Block,Finish};
typedef enum STATE_PROCESS STATE;
///建立PCB结构体
struct PCB_NODE{
int id; ///进程标识数
int priority; ///进程优先数
int arriveTime; ///进程到达时间
void queueWalk(PCB *queueHead)
③模拟就绪队列操作函数定义:
///进程插入到就绪队列
void readyQueuePush(PCB *process)
///优先数最大的进程出列
PCB * readyQueuePop()
///每个时间片更新就绪队列中的进程信息
void readyQueueUpdate(int timeSlice,PCB *pcb)
if(readyQueueNum == 0 && blockQueueNum == 0 && cpuBusy == 0){
printf("就绪队列、阻塞队列和CPU当前无进程运行,退出\n");
break;
}///end if
if(cpuBusy == 0){ ///CPU空闲,选择一个进程进入CPU
///选择就绪队列优先级最高的进程作为CPU运行进程
cpuProcess = readyQueuePop();
}else{
///就绪队列中没有进程,改为选择阻塞队列优先级最高的进程
cpuProcess = blockQueuePop();
}
cpuProcess->cpuTime = 0; ///设置当前运行进程占用CPU时间
}
printf("\n模拟进程动态优先权调度算法结束.\n");
return 0;
(2)动态优先权调度算法流程图
(2)实验结果
①第1个时间片后:
②第2个时间片后:
③第3个时间片后:
④第4个时间片后:
⑤第5个时间片后:
⑥第6个时间片后:
⑦第7个时间片后:
⑧第8个时间片后:
⑨第9个时间片后:
⑩第10个时间片后:
⑪第11个时间片后:
⑫第12个时间片后:
⑬第13个时间片后:
⑭第14个时间片后:
⑮第15个时间片后:
⑯第16个时间片后:
⑰第17个时间片后:
⑱第18个时间片后:
⑲第19个时间片后:
⑳第20个时间片后:
(3)实验结果分析
①调度算法开始之前进程PCB信息为:
②调度算法结束之后进程PCB信息为:
③调度算法分析:
队列头可运行进程
最高优先级
最低优先级
教 师 评 价
评定项目
A
B
C
D
评定项目
A
B
C
D
算法正确
界面美观,布局合理
程序结构合理
操作熟练
语法、语义正确
解析完整
实验结果正确
文字流畅
报告规范
题解正确
其他:
评价教师签名:
年月日
pHead = initData(); ///初始化进程PCB,返回进程头指针
pro = pHead + 1; ///pro指向PCB中第一个进程
readyQueueUpdate(timeSlice,pro); ///根据进程到达时间将新建进程加入绪队列
///模拟动态优先权进程调度
while(true){
B
2
6
C
4
4
D
6
5
E
8
2
(2)每个用来标识进程的进程控制块PCB可用结构来描述,包括以下字段(用不到的字段可以不定义)。
进程标识数ID。
进程优先数PRIORITY,并规定优先数越大的进程,其优先权越高。
进程已占用CPU时间CPUTIME。
进程还需占用的CPU时间ALLTIME。当进程运行完毕时,ALLTIME变为0。
三、实验内容
(1)用C、C++、Java语言编程实现对5个进程采用动态优先权调度算法进行调度的过程。数据如下:
5个进程的到达时刻和服务时间见下表,忽略I/O以及其它开销时间,使用动态优先权算法进行调度,优先权初始值为100,请输出各个进程的完成时刻、周转时间、带权周转时间。
进程
到达时刻
服务时间
A
0
3
}///end if
///更新就绪队列和阻塞队列中的进程信息
blockQueueUpdate();
readyQueueUpdate来自百度文库timeSlice,pro);
///查看就绪队列和阻塞队列的进程信息
readyQueueWalk();
blockQueueWalk();
if(cpuBusy == 1 && readyQueueNum > 0 &&
《操作系统》
实验题目
进程调度算法模拟
一、实验目的
通过对进程调度算法的模拟,进一步理解进程的基本概念,加深对进程运行状态和进程调度过程、调度算法的理解。
二、设备与环境
(1)硬件设备:PC机一台
(2)软件环境:安装Windows操作系统或者Linux操作系统,并安装相关的程序开发环境,如C \C++\Java等编程语言环境。
进程的阻塞时间STARTBLOCK,表示当进程再运行STARTBLOCK个时间片后,进程将进入阻塞状态。
进程被阻塞的时间BLOCKTIME,表示已阻塞的进程再等待BLOCKTIME个时间片后,将转换成就绪状态。
进程状态STATE。
队列指针NEXT,用来将PCB排成队列。
(3)优先数改变的原则:
进程在就绪队列中呆一个时间片,优先数增加1。
};
typedef struct PCB_NODE PCB;
②模拟进程队列操作函数定义:
///进程入列
void queuePush(PCB *process, PCB *queueHead)
///进程出列
void queuePop(PCB *process, PCB *queueHead)
///查看队列中进程信息
此外,优先级可以由系统动态确定。例如有些进程为I/O密集型,其多数时间用来等待I/O结束。当这样的进程需要CPU时,应立即分配给它CPU,以便启动下一个I/O请求,这样就可以在另一个进程计算的同时执行I/O操作。使这类I/O密集型进程长时间等待只会造成它无谓地长时间占用内存。使I/O密集型进程获得较好服务的一种简单算法是,将其优先级设为1/f,f为该进程在上一时间片中所占的部分。如果一个在其50ms的时间片中只使用1ms的进程的优先级为50,而在阻塞之前用掉25ms的进程优先级为2,使用掉全部时间片的进程优先级为1。
这样,可以很方便地将一组进程按优先级分成若干类,并在各类之间采用优先级调度,而在各类进程的内部采用轮转调度。如下图为一个具有4类优先级的系统,其调度算法如下:只要存在优先级为第4类的可运行进程,就按照轮转法为每个进程运行一个时间片,此时不理会较低优先级的进程。若第4类进程为空,则按照轮转法运行第3类进程。若第4类和第3类均为空,则按照轮转法运行第2类进程。如果不偶尔对优先级进行调整,则低优先级进程很可能会产生饥饿现象。
cpuProcess->state = Run; ///设置当前运行进程的状态
cpuBusy = 1; ///设置CPU当前状态为忙
}///end if
timeSlice ++; ///当前时间片加1
printf("\n第%d个时间片后:\n",timeSlice);
cpuWord(cpuProcess); ///模拟CPU执行1个时间片的操作
void cpuWord(PCB *cpuProcess)
⑥主函数关键代码:
int timeSlice = 0; ///模拟CPU时间片
int cpuBusy = 0; ///模拟CPU状态
PCB *cpuProcess = NULL; ///当前CPU执行的进程
PCB *pHead,*pro; ///进程PCB头指针
cpuProcess->priority < readyMaxPriority()){
blockQueuePush(cpuProcess); ///需抢占CPU,当前执行的进程调入阻塞队列
cpuProcess = readyQueuePop(); ///从就绪队列中选择优先级最高的进程运行
}///end if
///返回就绪队列最大优先数的值
int readyMaxPriority()
///查看就绪队列中的进程信息
void readyQueueWalk()
④模拟阻塞队列操作函数定义:
///进程插入到阻塞队列
void blockQueuePush(PCB *process)
///优先数最大的进程出列
PCB * blockQueuePop()
///每个时间片更新阻塞队列中进程的信息
void blockQueueUpdate()
///查看阻塞队列中的进程信息
void blockQueueWalk()
⑤模拟动态优先权进程调度函数定义:
///初始化进程PCB数据,返回PCB头指针
PCB * initData()
///模拟CPU执行1个时间片的操作
进程每运行一个时间片,优先数减3。
(4)为了清楚地观察每个进程的调度过程,程序应将每个时间片内的进程的情况显示出来,包括正在运行的进程,处于就绪队列中的进程和处于阻塞队列中的进程。
(5)分析程序运行的结果,谈一下自己的认识。
四、实验结果及分析
(1)实验关键代码
①模拟PCB数据结构定义:
///枚举进程的状态:新建、就绪、执行、阻塞、终止
int cpuTime; ///进程已占用CPU时间
int allTime; ///进程还需占用CPU时间
int blockTime; ///进程已阻塞时间
STATE state; ///进程状态
struct PCB_NODE *prev; ///PCB前指针
struct PCB_NODE *next; ///PCB后指针
进程ID
到达时间
服务时间
结束时间
周转时间
带权周转时间
0
0
3
10
10
3.3
1
2
6
20
18
3.0
2
4
4
16
12
3.0
3
6
5
18
12
2.4
4
8
2
13
5
2.5
(4)实验心得
通过进程动态优先权调度算法的模拟,对进程的运行状态,进程PCB数据结构,进程调度算法有了更深的理解。动态优先权调度算法为了防止高优先级进程无休止地运行下去,调度程序在每个时钟滴答(即每个时钟中断)降低当前进程的优先级。如果这个动作导致该进程的优先级低于次高优先级的进程,则进行进程切换,可以避免低优先级进程长时间的饥饿等待。
if(cpuProcess->allTime == 0){ ///若当前执行进程还需CPU时间片为0
cpuProcess->state = Finish; ///设置当前进程状态为终止
free(cpuProcess); ///释放该进程的PCB内存空间
cpuBusy = 0; ///CPU状态设置为空闲
enum STATE_PROCESS {New,Ready,Run,Block,Finish};
typedef enum STATE_PROCESS STATE;
///建立PCB结构体
struct PCB_NODE{
int id; ///进程标识数
int priority; ///进程优先数
int arriveTime; ///进程到达时间
void queueWalk(PCB *queueHead)
③模拟就绪队列操作函数定义:
///进程插入到就绪队列
void readyQueuePush(PCB *process)
///优先数最大的进程出列
PCB * readyQueuePop()
///每个时间片更新就绪队列中的进程信息
void readyQueueUpdate(int timeSlice,PCB *pcb)
if(readyQueueNum == 0 && blockQueueNum == 0 && cpuBusy == 0){
printf("就绪队列、阻塞队列和CPU当前无进程运行,退出\n");
break;
}///end if
if(cpuBusy == 0){ ///CPU空闲,选择一个进程进入CPU