1.实验目的:
加深对进程的概念和进程调度过程、算法的理解。
2.实验内容:
①关于进程调度算法的描述:
- 先来先服务调度算法(FSFS):当在进程调度中采用该算法时,系统将按照进程到达的先后次序来进行调度,或者说它是优先考虑在系统中等待时间最长的进程,为之分配处理机,使之投之运行,该进程一直运行到完成或发生某事件而阻塞后,进程调度程序才将处理机分配给其它进程。
- 时间轮转调度算法(Round-Robin):系统将所有的就绪进程按FCFS排成一个就绪队列。系统可设置每隔一定时间(如30ms)便产生一次中断,去激活进程调度程序进行调度,把CPU分配给队首进程,并令其执行一个时间片。当它运行完毕后,又把处理机分配给就绪队列中断的队首进程,也让它执行一个时间片。这样就可以保证就绪队列中的所有进程在确定的时间段内,都能获得一个时间片的处理机时间。
- 动态优先级算法(Dynamic-Priority):动态优先级是指在创建进程之前,先赋予其一个优先级,然后其随进程的推进或等待时间的增加而改变,以便获得更好的调度性能。例如,可以规定在就绪队列中的进程随其等待时间的增长,使其优先级相应提高。若所有的进程都具有相同优先级初值,则最先进入就绪队列的进程会因其优先级变得最高,而优先获得处理机,这相当于FCFS算法。若所有的就绪进程具有不相同的优先级初值,那么对于优先级初值低的进程,在等待了足够的时间后,也可以获得处理机。当采用抢占式调度方式时,若再规定当前进程的优先级随运行时间的推移而下降,则可防止一个长作业长期地垄断处理机。
②用C或C++语言设计一个队n个并发进程进行调度的程序,每个进程由一个进程控制块(PCB)结构表示,该进程控制块的内容见设计思路里PCB的定义。
3.设计思路
- 进程控制块(PCB)的定义如下:
typedef struct process_pcb {
int ID; //进程标识
int priority; //进程优先级
int arrive_time; //进程到达时间
int service_time; //进程需要总的服务时间
int start_time; //进程开始执行时间
int end_time; //进程结束时间
int all_time; //进程仍然需要运行时间
int cpu_time; //进程已占用cpu时间
string state; //进程状态
} PCB;
- 总体流程
-
进度调度算法流程
预期运行结果展示:
代码:
我自己写了一个500行的代码,虽然成功模拟了过程,但是代码姿势丑的一批,在这里贴一下好看的标程吧...
#include <iostream>
#include <queue>
#include<algorithm>
using namespace std;
//进程三种状态,这里增加一种,表示虽然输入,但是还没有到达进入系统时刻
typedef enum ProcessState{Executing, Ready, Finish, Unarrive}STATE;
//用于打印进程三种状态
char* StateString[] = {"Executing", "Ready", "Finish", "--"};
typedef struct process_pcb
{
int ID; //进程标识
int priority; //进程优先数,值越大,优先级越高
int arrive_time; //进程到达时间,以时间片为单位
int service_time; //进程需要总的服务时间
int start_time; //进程开始执行时间
int end_time; //进程结束时间
int all_time; //进程仍然需要运行时间
int cpu_time; //进程已占用cpu时间
STATE state; //进程状态
}PCB;
//排序比较函数:按照进程到达时间升序排列
bool cmp_arrive_time(const PCB a, const PCB b);
//排序比较函数:按照进程优先数降序排序
bool cmp_priority(const PCB a, const PCB b);
//输入进程信息
void input_process();
//选择进程调度策略
int select_policy();
//打印所有进程信息
void print_all(int current);
//先来先服务算法
void FCFS();
//时间片轮转算法
void round_robin();
//动态优先级算法
void dynamic_prio();
PCB *running_process = NULL;//当前运行任务
vector<PCB> input_queue;//进程输入队列,如当前时刻小于进程到达时间,则该进程仍然在输入队列中
vector<PCB> ready_queue;//就绪队列
vector<PCB> finish_queue;//完成队列
int main()
{
printf("===================================================\n");
printf(" 操作系统进程调度模拟实验 \n");
printf("===================================================\n");
printf("\n");
input_process();
//-1标志为打印所有进程的初始状态
print_all(-1);
int policy = select_policy();
switch(policy)
{
case 1:
FCFS();
break;
case 2:
round_robin();
break;
case 3:
dynamic_prio();
break;
default:
FCFS();
break;
}
}
//按进程到达时间升序排列,先到达的排在队首
bool cmp_arrive_time(const PCB a, const PCB b)
{
return a.arrive_time < b.arrive_time;
}
//按进程优先级降序排列,优先级高的排在队首
//如优先级相同,先到的进程排在前面
bool cmp_priority(const PCB a, const PCB b)
{
if(a.priority != b.priority){
return a.priority > b.priority;
}else{
return a.arrive_time < b.arrive_time;
}
}
//选择进程调度策略
int select_policy()
{
printf("\n请选择调度算法(输入1、2、3选择):\n");
printf("1.先来先服务调度(FCFS) \n");
printf("2.时间片轮转调度(Round-Robin) \n");
printf("3.动态优先级调度(DynamicPriority) \n");
int n;
printf("请输入调度算法序号:");
while(scanf("%d",&n)){
if(n > 3 || n < 1){
printf("对不起,输入有误,请重新输入!\n");
}else{
break;
}
}
return n;
}
//输入进程信息
void input_process()
{
int num;
printf("请输入进程数量:");
scanf("%d",&num);
PCB pro;
for(int i = 1; i <= num; i++){
printf("\n请输入第%d个进程的到达时间、服务时间及优先级(以空格隔开):\n",i);
scanf("%d%d%d",&pro.arrive_time,&pro.service_time,&pro.priority);
pro.ID = i;
pro.all_time = pro.service_time;
pro.cpu_time = 0;
pro.start_time = -1;//开始时间、结束时间默认为-1,表示尚未被调度过
pro.end_time = -1;
pro.state = Unarrive;//初始化为尚未进入到达
input_queue.push_back(pro);
}
//按照到达时间升序排队
sort(input_queue.begin(), input_queue.end(), cmp_arrive_time);
}
//打印单个进程的信息
void print_process(PCB* pro)
{
if(pro == NULL){
return;
}
printf("%4d%10d%10d%8d%10s", pro->ID, pro->arrive_time, pro->service_time, pro->priority, StateString[pro->state]);
//如进程尚未开始,则开始时间、结束时间以及剩余时间以--表示
//如进程已经开始,但未结束,则其结束时间以--表示
if(pro->start_time == -1){
printf("%10s%10s%10s", "--", "--", "--");
}else{
if(pro->end_time == -1){
printf("%10d%10s%10d", pro->start_time, "--", pro->all_time);
}else{
printf("%10d%10d%10d", pro->start_time, pro->end_time, pro->all_time);
}
}
//仅进程结束后,才统计其周转时间及加权周转时间
if(pro->state == Finish)
{
printf("%10d%10.2lf\n", pro->end_time - pro->arrive_time, (float)(pro->end_time - pro->arrive_time)/(float)pro->service_time);
}else{
printf("%10s%10s\n", "--", "--");
}
}
//打印所有进程的信息,-1为打印进程初始输入状态
void print_all(int current)
{
if(current == -1){
printf("\n进程初始状态:\n", current);
}else{
printf("\n当前时刻为:%d\n", current);
}
printf("进程号 到达时间 服务时间 优先级 状态 开始时间 结束时间 剩余时间 周转时间 带权周转时间\n");
//打印正在运行的进程
if(running_process != NULL){
print_process(running_process);
}
vector<PCB>::iterator it;
//打印就绪队列中的进程
for(it = ready_queue.begin(); it != ready_queue.end(); it ++){
print_process(&(*it));
}
//打印完成队列中的进程
for(it = finish_queue.begin(); it != finish_queue.end(); it ++){
print_process(&(*it));
}
//打印仍在输入队列中的进程
for(it = input_queue.begin(); it != input_queue.end(); it ++){
print_process(&(*it));
}
}
//先来先服务算法
void FCFS()
{
int chip = 0;//初始的时间片为0
//需要调度标志,默认为true
bool need_schedule = true;
while(1)
{
//如当前无正在运行进程,同时输入队列和就绪队列都为空,则所有进程完成
if(!running_process && input_queue.empty() && ready_queue.empty()){
break;
}
//将输入队列中,到达时间小于等于当前时间片的进程放入就绪队列中,并从输入队列中删除
while(!input_queue.empty()){
PCB pro = input_queue[0];
if(pro.arrive_time <= chip){
pro.state = Ready;
//放入就绪队列队尾
ready_queue.push_back(pro);
//从输入队列中删除
input_queue.erase(input_queue.begin() + 0);
}else{
break;
}
}
//判断是否需要调度,如需要则从取出就绪队列队首进程进行调度
if(need_schedule && !ready_queue.empty())
{
running_process = new PCB;
*running_process = ready_queue[0];//取出就绪队首进程
ready_queue.erase(ready_queue.begin() + 0);//从就绪队列中删除之
//调度进程开始运行
running_process->start_time = chip;
running_process->state = Executing;
need_schedule = false;
}
print_all(chip);//打印当前时刻所有进程的信息
//当前运行任务完成1个时间片,更改其信息
if(running_process){
running_process->cpu_time += 1;
running_process->all_time -= 1;
if(running_process->all_time == 0){//任务运行结束
running_process->end_time = chip + 1;
running_process->state = Finish;
finish_queue.push_back(*running_process);//将其放入完成队列中
delete running_process;
running_process = NULL;
need_schedule = true;
}else{
//FCFS仅当该进程运行完毕后,才调度下一个任务
need_schedule = false;
}
}
chip += 1;
}
//所有任务全部完成后,打印一次
print_all(chip);
}
//时间片轮转算法
void round_robin()
{
int chip = 0;//初始的时间片为0
bool need_schedule = true;
while(1)
{
//如当前无正在运行进程,同时输入队列和就绪队列都为空,则所有进程完成
if(!running_process && input_queue.empty() && ready_queue.empty()){
break;
}
//将输入队列中,到达时间小于等于当前时间片的进程放入就绪队列中,并从输入队列中删除
while(!input_queue.empty()){
PCB pro = input_queue[0];
if(pro.arrive_time <= chip){
pro.state = Ready;
//放入就绪队列队尾
ready_queue.push_back(pro);
//从输入队列中删除
input_queue.erase(input_queue.begin() + 0);
}else{
break;
}
}
//判断是否需要调度,如需要则取出就绪队列队首进程进行调度
if(need_schedule && !ready_queue.empty())
{
running_process = new PCB;
*running_process = ready_queue[0];//从就绪队首中取出
ready_queue.erase(ready_queue.begin() + 0);//从就绪队列中删除之
//调度进程开始运行
if(running_process->start_time == -1){//首次运行
running_process->start_time = chip;
}
running_process->state = Executing;
need_schedule = false;
}
print_all(chip);//打印当前时刻所有进程的信息
//当前运行任务完成1个时间片,判断该任务是否已经完成
if(running_process){
running_process->cpu_time += 1;
running_process->all_time -= 1;
if(running_process->all_time == 0){//任务运行结束
running_process->end_time = chip + 1;
running_process->state = Finish;
finish_queue.push_back(*running_process);//将其放入完成队列中
delete running_process;
running_process = NULL;
need_schedule = true;
}else{//任务没有完成,如果就绪队列中仍有任务,则轮转调度,否则不调度
if(!ready_queue.empty()){
running_process->state = Ready;
ready_queue.push_back(*running_process);//将其放回就绪队列中
delete running_process;
running_process = NULL;
need_schedule = true;
}else{
need_schedule = false;
}
}
}
chip += 1;
}
//所有任务全部完成后,打印一次
print_all(chip);
}
//动态优先级算法
void dynamic_prio()
{
int chip = 0;//初始的时间片为0
bool need_schedule = true;
while(1)
{
//如当前无正在运行进程,同时输入队列和就绪队列都为空,则所有进程完成
if(!running_process && input_queue.empty() && ready_queue.empty()){
break;
}
//将输入队列中,到达时间小于等于当前时间片的进程放入就绪队列中,并从输入队列中删除
while(!input_queue.empty()){
PCB pro = input_queue[0];
if(pro.arrive_time <= chip){
pro.state = Ready;
//放入就绪队列队尾
ready_queue.push_back(pro);
//从输入队列中删除
input_queue.erase(input_queue.begin() + 0);
}else{
break;
}
}
if(!ready_queue.empty()){
//将就绪进程按照优先级降序排列
sort(ready_queue.begin(), ready_queue.end(), cmp_priority);
}
//判断是否需要调度,如需要则取出就绪队列队首进程进行调度
if(need_schedule && !ready_queue.empty())
{
running_process = new PCB;
*running_process = ready_queue[0];//取出就绪队首进程
ready_queue.erase(ready_queue.begin() + 0);//从就绪队列中删除之
//调度进程开始运行
if(running_process->start_time == -1){//首次运行
running_process->start_time = chip;
}
running_process->state = Executing;
need_schedule = false;
}
print_all(chip);//打印当前时刻,所有进程的信息
//当前运行任务完成1个时间片,判断该任务是否已经完成
if(running_process){
running_process->cpu_time += 1;
running_process->all_time -= 1;
if(running_process->all_time == 0){//任务运行结束
running_process->end_time = chip + 1;
running_process->state = Finish;
finish_queue.push_back(*running_process);//将其放入完成队列中
delete running_process;
running_process = NULL;
need_schedule = true;
}else{//任务没有完成,如果就绪队列中仍有任务,且优先级大于本任务的优先级,则轮转调度,否则不调度
if(running_process->priority > 1){
running_process->priority -= 1;//优先级最小为1
}
if(!ready_queue.empty() && ready_queue[0].priority > running_process->priority){
running_process->state = Ready;
ready_queue.push_back(*running_process);//将其放回就绪队列中
delete running_process;
running_process = NULL;
need_schedule = true;
}else{
need_schedule = false;
}
}
}
chip += 1;
}
//所有任务全部完成后,打印一次
print_all(chip);
}
以下是自己的代码,主要是丑在输出函数,没利用好%10d对齐格式。
并且在设计FCFS和Round-Robin时偷懒,少用了队列,导致代码就比较丑陋。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<cmath>
#include<iomanip>
#include<algorithm>
#define MAX_PROCESS_NUM 100
using namespace std;
typedef struct process_pcb {
int ID; //进程标识
int priority; //进程优先级
int arrive_time; //进程到达时间
int service_time; //进程需要总的服务时间
int start_time; //进程开始执行时间
int end_time; //进程结束时间
int all_time; //进程仍然需要运行时间
int cpu_time; //进程已占用cpu时间
string state; //进程状态
process_pcb() {}
process_pcb(int ID,int priority,int arrive_time,int service_time,int start_time,int end_time,
int all_time,int cpu_time,string state):ID(ID),priority(priority),
arrive_time(arrive_time),service_time(service_time),start_time(start_time),
end_time(end_time),all_time(all_time),cpu_time(cpu_time),state(state) {}
} PCB;
queue<process_pcb>q; //存放进程的队列
queue<process_pcb>qq; //用来存放已经完成的进程的队列
int process_num;
PCB pcb;
PCB temp_pcb[MAX_PROCESS_NUM];
string Executing="Executing";
string Ready="Ready";
string Finish="Finish";
void print_state(int tag) {
if(tag==-1)
cout<<"进程初始状态:"<<endl;
else
cout<<"当前时刻: "<<tag<<endl;
cout<<"进程号 "<<"到达时间 "<<"服务时间 "<<"优先级 "<<"状态 "<<"开始时间 "<<"结束时间 "<<"剩余时间 "<<"周转时间 "<<"带权周转时间 "<<endl;
int siz=q.size();
for(int i=1;i<=siz;i++) {
pcb=q.front();
q.pop();
q.push(pcb);
cout<<" ";
cout<<pcb.ID<<'\t'<<" "<<pcb.arrive_time<<'\t'<<" "<<pcb.service_time<<'\t'<<" "<<pcb.priority<<'\t'<<" ";
if(pcb.state.size()==0) //状态
cout<<" "<<"--"<<'\t'<<" ";
else {
if(pcb.state==Executing)
cout<<pcb.state<<" ";
else
cout<<pcb.state<<'\t'<<" ";
}
if(pcb.start_time==-1) //开始时间
cout<<"--"<<'\t'<<" ";
else
cout<<pcb.start_time<<'\t'<<" ";
if(pcb.end_time==-1) //结束时间
cout<<"--"<<'\t'<<" ";
else
cout<<pcb.end_time<<'\t'<<" ";
if(pcb.all_time==-1) //剩余时间
cout<<"--"<<'\t'<<" ";
else
cout<<pcb.all_time<<'\t'<<" ";
if(pcb.state!=Finish) //周转时间
cout<<"--"<<'\t'<<" ";
else {
int res;
res=pcb.end_time-pcb.arrive_time;
cout<<res<<'\t'<<" ";
}
if(pcb.state!=Finish) //带权周转时间
cout<<"--";
else {
double res;
res=pcb.end_time-pcb.arrive_time;
res=res/pcb.service_time;
cout<<fixed<<setprecision(2)<<res;
}
cout<<endl;
}
siz=qq.size();
for(int i=1;i<=siz;i++) {
pcb=qq.front();
qq.pop();
qq.push(pcb);
cout<<" ";
cout<<pcb.ID<<'\t'<<" "<<pcb.arrive_time<<'\t'<<" "<<pcb.service_time<<'\t'<<" "<<pcb.priority<<'\t'<<" ";
if(pcb.state.size()==0) //状态
cout<<" "<<"--"<<'\t'<<" ";
else {
if(pcb.state==Executing)
cout<<pcb.state<<" ";
else
cout<<pcb.state<<'\t'<<" ";
}
if(pcb.start_time==-1) //开始时间
cout<<"--"<<'\t'<<" ";
else
cout<<pcb.start_time<<'\t'<<" ";
if(pcb.end_time==-1) //结束时间
cout<<"--"<<'\t'<<" ";
else
cout<<pcb.end_time<<'\t'<<" ";
if(pcb.all_time==-1) //剩余时间
cout<<"--"<<'\t'<<" ";
else
cout<<pcb.all_time<<'\t'<<" ";
if(pcb.state!=Finish) //周转时间
cout<<"--"<<'\t'<<" ";
else {
int res;
res=pcb.end_time-pcb.arrive_time;
cout<<res<<'\t'<<" ";
}
if(pcb.state!=Finish) //带权周转时间
cout<<"--";
else {
double res;
res=pcb.end_time-pcb.arrive_time;
res=res/pcb.service_time;
cout<<fixed<<setprecision(2)<<res;
}
cout<<endl;
}
cout<<endl;
}
void set_state(int time) {
if(q.front().arrive_time>time)
return;
if(q.front().start_time==-1) { //第一次调用进程时,为其赋之开始时间,且此时剩余时间为总服务时间
q.front().start_time=time;
q.front().all_time=q.front().service_time;
}
q.front().state=Executing;
q.push(q.front());
q.pop();
int siz=q.size();
for(int i=1;i<siz;i++) {
if(q.front().arrive_time<=time)
q.front().state=Ready;
q.push(q.front());
q.pop();
}
}
void FCFS() {
int time=0;
print_state(time++);
//设置开始时的进程状态(只设置状态)
for(int i=1;i<=process_num;i++) {
while(q.front().state!=Finish) { //一直到进程执行结束才跳出循环
set_state(time);
print_state(time++); //打印当前所有进程状态
q.front().all_time--; //所需时间减一
if(q.front().all_time==0) { //如果执行结束,设置状态和结束时间,并且将进程放到队尾
q.front().state=Finish;
q.front().end_time=time;
qq.push(q.front());
q.pop();
break;
}
}
}
print_state(time);//打印最后全部完成的状态
}
void Round_Robin() {
int time=0,finished_num=0; //time代表当前时刻,finished_num代表已经完成的进程的数量
print_state(time++);
while(true) {
set_state(time);
print_state(time++); //输出此时所有进程的状态
pcb=q.front();
q.pop(); //将此进程移出队首
pcb.all_time--; //所需要的总时间减一
pcb.state=Ready; //状态设为Ready
if(pcb.all_time==0) { //如果所需要的时间为0,则代表进程执行完毕
pcb.state=Finish; //设状态为Finish
pcb.end_time=time; //设置结束时间
finished_num++; //已经完成的进程数量加1
qq.push(pcb);
}
else
q.push(pcb); //将进程放入队尾
if(finished_num==process_num) { //如果已完成的进程数量等于总进程数量,则跳出循环
print_state(time);
break;
}
}
}
struct cmp {
bool operator() (const process_pcb &p,const process_pcb &q) {
return p.priority<q.priority;
}
};
priority_queue<process_pcb,vector<process_pcb>,cmp>pq;
/*动态优先级算法中,pq为就绪队列,q存放还未到的序列,qq存放已经完成的序列*/
void print_state_DynamicPriority(int tag,int time) {
cout<<"当前时刻: "<<time<<endl;
cout<<"进程号 "<<"到达时间 "<<"服务时间 "<<"优先级 "<<"状态 "<<"开始时间 "<<"结束时间 "<<"剩余时间 "<<"周转时间 "<<"带权周转时间 "<<endl;
if(tag!=0) {
cout<<pcb.ID<<'\t'<<" "<<pcb.arrive_time<<'\t'<<" "<<pcb.service_time<<'\t'<<" "<<pcb.priority<<'\t'<<" ";
if(pcb.state.size()==0) //状态
cout<<" "<<"--"<<'\t'<<" ";
else {
if(pcb.state==Executing)
cout<<pcb.state<<" ";
else
cout<<pcb.state<<'\t'<<" ";
}
if(pcb.start_time==-1) //开始时间
cout<<"--"<<'\t'<<" ";
else
cout<<pcb.start_time<<'\t'<<" ";
if(pcb.end_time==-1) //结束时间
cout<<"--"<<'\t'<<" ";
else
cout<<pcb.end_time<<'\t'<<" ";
if(pcb.all_time==-1) //剩余时间
cout<<"--"<<'\t'<<" ";
else
cout<<pcb.all_time<<'\t'<<" ";
if(pcb.state!=Finish) //周转时间
cout<<"--"<<'\t'<<" ";
else {
int res;
res=pcb.end_time-pcb.arrive_time;
cout<<res<<'\t'<<" ";
}
if(pcb.state!=Finish) //带权周转时间
cout<<"--";
else {
double res;
res=pcb.end_time-pcb.arrive_time;
res=res/pcb.service_time;
cout<<fixed<<setprecision(2)<<res;
}
cout<<endl;
}
int siz=pq.size();
struct process_pcb temp;
queue<process_pcb>temp_q;//鉴于优先队列会自动排序,所以输出的时候可能会一直输出优先级高的,所以这里用个辅助队列将进程保存,最后再放进优先队列
for(int i=1;i<=siz;i++) {
temp=pq.top();pq.pop();
temp_q.push(temp);
cout<<temp.ID<<'\t'<<" "<<temp.arrive_time<<'\t'<<" "<<temp.service_time<<'\t'<<" "<<temp.priority<<'\t'<<" ";
if(temp.state.size()==0) //状态
cout<<" "<<"--"<<'\t'<<" ";
else {
if(temp.state==Executing)
cout<<temp.state<<" ";
else
cout<<temp.state<<'\t'<<" ";
}
if(temp.start_time==-1) //开始时间
cout<<"--"<<'\t'<<" ";
else
cout<<temp.start_time<<'\t'<<" ";
if(temp.end_time==-1) //结束时间
cout<<"--"<<'\t'<<" ";
else
cout<<temp.end_time<<'\t'<<" ";
if(temp.all_time==-1) //剩余时间
cout<<"--"<<'\t'<<" ";
else
cout<<temp.all_time<<'\t'<<" ";
if(temp.state!=Finish) //周转时间
cout<<"--"<<'\t'<<" ";
else {
int res;
res=temp.end_time-temp.arrive_time;
cout<<res<<'\t'<<" ";
}
if(temp.state!=Finish) //带权周转时间
cout<<"--";
else {
double res;
res=temp.end_time-temp.arrive_time;
res=res/temp.service_time;
cout<<fixed<<setprecision(2)<<res;
}
cout<<endl;
}
while(!temp_q.empty()) {
pq.push(temp_q.front());
temp_q.pop();
}
siz=q.size();
for(int i=1;i<=siz;i++) {
temp=q.front();q.pop();
q.push(temp);
cout<<temp.ID<<'\t'<<" "<<temp.arrive_time<<'\t'<<" "<<temp.service_time<<'\t'<<" "<<temp.priority<<'\t'<<" ";
if(temp.state.size()==0) //状态
cout<<" "<<"--"<<'\t'<<" ";
else {
if(temp.state==Executing)
cout<<temp.state<<" ";
else
cout<<temp.state<<'\t'<<" ";
}
if(temp.start_time==-1) //开始时间
cout<<"--"<<'\t'<<" ";
else
cout<<temp.start_time<<'\t'<<" ";
if(temp.end_time==-1) //结束时间
cout<<"--"<<'\t'<<" ";
else
cout<<temp.end_time<<'\t'<<" ";
if(temp.all_time==-1) //剩余时间
cout<<"--"<<'\t'<<" ";
else
cout<<temp.all_time<<'\t'<<" ";
if(temp.state!=Finish) //周转时间
cout<<"--"<<'\t'<<" ";
else {
int res;
res=temp.end_time-temp.arrive_time;
cout<<res<<'\t'<<" ";
}
if(temp.state!=Finish) //带权周转时间
cout<<"--";
else {
double res;
res=temp.end_time-temp.arrive_time;
res=res/temp.service_time;
cout<<fixed<<setprecision(2)<<res;
}
cout<<endl;
}
siz=qq.size();
for(int i=1;i<=siz;i++) {
temp=qq.front();qq.pop();
qq.push(temp);
cout<<temp.ID<<'\t'<<" "<<temp.arrive_time<<'\t'<<" "<<temp.service_time<<'\t'<<" "<<temp.priority<<'\t'<<" ";
if(temp.state.size()==0) //状态
cout<<" "<<"--"<<'\t'<<" ";
else {
if(temp.state==Executing)
cout<<temp.state<<" ";
else
cout<<temp.state<<'\t'<<" ";
}
if(temp.start_time==-1) //开始时间
cout<<"--"<<'\t'<<" ";
else
cout<<temp.start_time<<'\t'<<" ";
if(temp.end_time==-1) //结束时间
cout<<"--"<<'\t'<<" ";
else
cout<<temp.end_time<<'\t'<<" ";
if(temp.all_time==-1) //剩余时间
cout<<"--"<<'\t'<<" ";
else
cout<<temp.all_time<<'\t'<<" ";
if(temp.state!=Finish) //周转时间
cout<<"--"<<'\t'<<" ";
else {
int res;
res=temp.end_time-temp.arrive_time;
cout<<res<<'\t'<<" ";
}
if(temp.state!=Finish) //带权周转时间
cout<<"--";
else {
double res;
res=temp.end_time-temp.arrive_time;
res=res/temp.service_time;
cout<<fixed<<setprecision(2)<<res;
}
cout<<endl;
}
}
void set_priority_and_state(int time) {
int siz=pq.size();
queue<process_pcb>temp_q;
struct process_pcb temp;
for(int i=1;i<=siz;i++) {
temp=pq.top();pq.pop();
temp.priority++;
temp_q.push(temp);
}
while(!temp_q.empty()) {
pq.push(temp_q.front());
temp_q.pop();
}
while(!q.empty()) {
if(q.front().arrive_time<=time) {
q.front().state=Ready;
pq.push(q.front());
q.pop();
}
else
break;
}
}
void DynamicPriority() { //动态优先级算法
int time=0;
print_state_DynamicPriority(0,time++);//打印初始状态
for(int i=1;i<=process_num;i++) {
pcb=q.front();
if(pcb.arrive_time<=time) { //将第一时刻到达的进程放入就绪队列里
pcb.state=Ready;
pq.push(pcb);
q.pop();
}
else
break;
}
for(int i=1;i<=process_num;i++) {
if(pq.empty()) { //处理就绪队列为空的状态
while(true) {
print_state_DynamicPriority(0,time++);
set_priority_and_state(time);
if(!pq.empty())
break;
}
}
pcb=pq.top();
pq.pop();
pcb.state=Executing;//设置正在运行的进程各种变量
pcb.start_time=time;
pcb.all_time=pcb.service_time;
while(pcb.state!=Finish) {
print_state_DynamicPriority(1,time++);
set_priority_and_state(time);//增加就绪队列里的优先级并且将此时刻到达的进程放入就绪队列
pcb.all_time--;//剩余时间减一
if(pcb.all_time==0) { //进程执行完毕,进行处理
pcb.end_time=time;
pcb.state=Finish;
qq.push(pcb);
}
}
}
print_state_DynamicPriority(0,time++);//打印最终的状态
}
void initPCB(process_pcb &pcb) { //将所有进程初始化
pcb=process_pcb(-1,-1,-1,-1,-1,-1,-1,-1,"");
}
bool cmpp(process_pcb p,process_pcb q) {
return p.arrive_time<q.arrive_time;
}
int main() {
cout<<"=============================================="<<endl;
cout<<" 操作系统进程调度模拟实验"<<endl;
cout<<"=============================================="<<endl;
cout<<endl;
cout<<"请输入进程数量: ";
cin>>process_num;
for(int i=1;i<=process_num;i++) {
cout<<"请输入第 "<<i<<" 个进程的到达时间、服务时间及优先级(以空格隔开):"<<endl;
initPCB(temp_pcb[i]);
cin>>temp_pcb[i].arrive_time>>temp_pcb[i].service_time>>temp_pcb[i].priority;
temp_pcb[i].ID=i;
cout<<endl;
}
sort(temp_pcb+1,temp_pcb+process_num+1,cmpp);
for(int i=1;i<=process_num;i++)
q.push(temp_pcb[i]);
int select=-1;
print_state(select);
cout<<"请选择调度算法<输入1、2、3选择>:"<<endl;
cout<<"1.先来先服务调度<FCFS>"<<endl;
cout<<"2.时间片轮转调度<Round-Robin>"<<endl;
cout<<"3.动态优先级调度<DynamicPriority>"<<endl;
cout<<"请输入调度算法序号:";
cin>>select;
cout<<endl;
switch(select) {
case 1 : FCFS();break;
case 2 : Round_Robin();break;
case 3 : DynamicPriority();break;
}
}