操作系统-进程调度模拟算法(FCFS/Round-Robin/DynamicPriority)

1.实验目的:

加深对进程的概念和进程调度过程、算法的理解。

2.实验内容:

①关于进程调度算法的描述:

  1. 先来先服务调度算法(FSFS):当在进程调度中采用该算法时,系统将按照进程到达的先后次序来进行调度,或者说它是优先考虑在系统中等待时间最长的进程,为之分配处理机,使之投之运行,该进程一直运行到完成或发生某事件而阻塞后,进程调度程序才将处理机分配给其它进程。
  2. 时间轮转调度算法(Round-Robin):系统将所有的就绪进程按FCFS排成一个就绪队列。系统可设置每隔一定时间(如30ms)便产生一次中断,去激活进程调度程序进行调度,把CPU分配给队首进程,并令其执行一个时间片。当它运行完毕后,又把处理机分配给就绪队列中断的队首进程,也让它执行一个时间片。这样就可以保证就绪队列中的所有进程在确定的时间段内,都能获得一个时间片的处理机时间。
  3. 动态优先级算法(Dynamic-Priority):动态优先级是指在创建进程之前,先赋予其一个优先级,然后其随进程的推进或等待时间的增加而改变,以便获得更好的调度性能。例如,可以规定在就绪队列中的进程随其等待时间的增长,使其优先级相应提高。若所有的进程都具有相同优先级初值,则最先进入就绪队列的进程会因其优先级变得最高,而优先获得处理机,这相当于FCFS算法。若所有的就绪进程具有不相同的优先级初值,那么对于优先级初值低的进程,在等待了足够的时间后,也可以获得处理机。当采用抢占式调度方式时,若再规定当前进程的优先级随运行时间的推移而下降,则可防止一个长作业长期地垄断处理机。

②用C或C++语言设计一个队n个并发进程进行调度的程序,每个进程由一个进程控制块(PCB)结构表示,该进程控制块的内容见设计思路里PCB的定义。

3.设计思路

  1. 进程控制块(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;

  2. 总体流程  
  3. 进度调度算法流程

预期运行结果展示:

 

 

代码:

我自己写了一个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;
    }
}

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值