一、实验名称:处理机调度
二、实验目的与要求
目的:通过本实验加深理解有关进程控制块、进程队列的概念,并体会和了解有关调度算法的基本原理。
要求:设计一个对N个并发的进程实现处理机调度的程序,调度算法可选用先来先服务、最高优先数、轮转法等任一种。
三、实验内容
• 在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。当就绪进程个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。本实验模拟在单处理器情况下的处理器调度,调度的策略采用先来先服务调度算法。
• 通过该程序可以了解OS中进程的几种状态,以及基本的调度进程的策略。
• 假定系统的并发度为五(最多可以创建5个进程),每一个进程用一个进程控制块PCB来代表,进程控制块的格式为:
进程名 |
要求运行时间 |
状态 |
指针 |
• 其中,进程名——作为进程的标识;
要求运行时间——假设进程需要运行的单位时间数;
状态——可假设有三种状态,“就绪”状态、“阻塞”状态和“结束”状态。新创建进程的初始状态都为“就绪”,用“R”表示,当一个进程运行结束后,它的状态为“结束”,用“E”表示,“阻塞”状态的进程用“B”表示。
指针——用指针指出下一个进程具有相同状态的进程控制块的首地址;
• 系统可以设置两个队列(就绪,堵塞)。
• 设计时通过控制台输入命令,如
New:新建进程,则增加一个pcb到就绪队列;
Run(finish):运行进程,则从就绪队列头部删除一进程并投入运行,显示运行状态,并顺利结束;
Run(wait):运行后堵塞,从就绪队列头部删除一进程并投入运行,显示运行1个时间单位后又堵塞,并将此进程加入到堵塞队列尾部;
Signal:唤醒进程,从堵塞队列头部将堵塞的进程加入到就绪队列尾部;
Show显示所有进程的进程控制块PCB的信息。
代码实现:
#include <iostream>
#include <cstring>
#include <windows.h>
using namespace std;
const int READY = 1; // 就绪
const int RUN =2; //运行
const int END = 3; // 结束
const int BLOCK=4; // 阻塞
typedef struct node { //进程控制块PCB
string Name;
int Runtime;
int Status = READY;
struct node *next=NULL;
} PCB;
PCB*ready_head=new PCB,*ready_tail=NULL,*block_head=new PCB,*block_tail=NULL;//就绪队列,阻塞队列
void New() {
cout<<"------新建进程------"<<endl;
PCB *process = new PCB;
if(ready_head->next ==NULL) {
ready_head->next = process;
} else {
ready_tail->next=process;
}
cout<<" 输入线程的名称:";
cin>>process->Name;
cout<<" 输入线程的运行时间:";
cin>>process->Runtime;
ready_tail=process;
cout<<" 进程创建成功!"<<endl;
cout<<endl;
}
void Run_finish() {
if (ready_head->next ==NULL) {
cout<<" 就绪队列为空!"<<endl;
return;
}
PCB* del=ready_head->next;
ready_head->next=ready_head->next->next;
cout<<endl<<" 进程 "<<del->Name<<" 运行完毕."<<endl;
delete del;
}
void Run_wait() {
if(ready_head->next ==NULL) {
cout<<" 就绪队列为空!"<<endl;
return;
}
PCB* process=ready_head->next;
ready_head->next=ready_head->next->next;
cout<<" 进程 "<<process->Name<<" 运行一个时间单位"<<endl;
process->Runtime--;
process->Status=BLOCK;
cout<<" 该进程阻塞..."<<endl;
if(block_head->next==NULL) {
block_head->next=process;
} else {
block_tail->next=process;
}
block_tail=process;
block_tail->next=NULL;
cout<<" 进程阻塞成功!"<<endl;
}
void Signal() {
if(block_head==NULL) {
cout<<" 阻塞队列为空!"<<endl;
return;
}
PCB *process=block_head->next;
block_head->next=block_head->next->next;
if(ready_head->next==NULL) {
ready_head->next=process;
} else {
ready_tail->next=process;
}
process->Status=READY;
ready_tail=process;
process->next=NULL;
cout<<process->Name<<"进程唤醒成功!"<<endl;
}
void Show() { /*输出队列信息*/
PCB*p;
p=ready_head->next;
cout<<"进程名 cpu_time 状态"<<endl;
while(p!=NULL) {
cout<<p->Name<<" "<<p->Runtime<<" ";
if(p->Status==1) {
cout<<"READY"<<endl;
} else if(p->Status==2) {
cout<<"RUN"<<endl;
} else if(p->Status==3) {
cout<<"END"<<endl;
} else {
cout<<"BLOCK"<<endl;
}
p=p->next;
}
p=block_head->next;
while(p!=NULL) {
cout<<p->Name<<" "<<p->Runtime<<" ";
if(p->Status==1) {
cout<<"READY"<<endl;
} else if(p->Status==2) {
cout<<"RUN"<<endl;
} else if(p->Status==3) {
cout<<"END"<<endl;
} else {
cout<<"BLOCK"<<endl;
}
p=p->next;
}
}
int main() {
while(true) {
cout<<"***************欢迎来到先来先服务调度算法***************"<<endl;
cout<<" 1.创建进程"<<endl;
cout<<" 2.运行并结束进程"<<endl;
cout<<" 3.运行后阻塞"<<endl;
cout<<" 4.唤醒进程"<<endl;
cout<<" 5.打印进程信息"<<endl;
cout<<" q.退去"<<endl;
cout<<"********************************************************"<<endl;
cout<<"请输入您的选择:"<<endl;
string cmd;
cin>>cmd;
if(cmd=="1") {
New();
} else if(cmd=="2") {
Run_finish();
} else if(cmd=="3") {
Run_wait();
} else if(cmd=="4") {
Signal();
} else if(cmd=="5") {
Show();
} else if (cmd=="q") {
break;
} else {
cout<<"错误输入!"<<endl;
}
}
return 0;
}
实验结果:
- 创建进程:实验截图(已创建p1为例),创建了p1,p2,p3
2. 运行并结束进程:实验截图
3. 运行后阻塞:实验截图
4. 唤醒进程:实验截图