操作系统之处理机调度
Posted 夏芷雨涵梦
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了操作系统之处理机调度相关的知识,希望对你有一定的参考价值。
题目描述:
在处理机三级调度系统中,编程仿真作业调度与进程调度。作业调度采用短作业优先的方式,进程调度采用优先级方式或时间片轮转方式。
源代码:
#include <iostream>
#include <stdlib.h>
#include <cstdio>
#define TIMELIMIT 6
#define PriLimit 5
#define work 5
using namespace std;
struct JCB //作业
int jname; //作业名
int start; //到达时间
int priority; //优先级
int worktime; //工作时间
JCB *next; //链接指针
;
struct PCB
int pname; //进程名
int time; //进程运行时间
char state; //运行状态
PCB* next;
;
void CreateJob(JCB* jobtable,int name) //创建作业,将作业放入作业调度表
//随机生成一个作业
JCB *p = new JCB;
p->jname=name;
p->start = rand()%5+1;
p->worktime = rand()%TIMELIMIT+1;
p->priority = rand()%PriLimit+1;
p->next = NULL;
JCB* now = jobtable;
if(now->next==NULL)
now->next = p;
else
if(p->start <= now->next->start)//新插入的作业到达时间比表中的第一个小,将新到的插入到表头
p->next = now->next;
now->next = p;
else//新插入的作业到达时间比表中的第一个大,向后查找
JCB *q = now->next;
while( (p->start > q->start) && (q->next!=NULL) )
q = q->next;
if( (p->start > q->start) && q->next==NULL) //比所有的都大,放到最后
q->next = p;
else if(p->start <= q->start)
JCB *t = now->next;
while(t->next!=q) //找到前驱节点
t = t->next;
t->next = p;
p->next = q;
void AddHoubei(JCB *jobtable,JCB *p,JCB *&jhead) //将作业p放入后备队列jhead,按短作业优先放置
JCB* q = jobtable;
while(q->next!=p && q->next!=NULL)// 找到p的前驱节点
q = q->next;
if(q->next==p)
q->next = p->next;
p->next = NULL;
if(jhead==NULL)
jhead = p;
else
if(p->worktime <= jhead->worktime)//优先级小的放在前边
p->next = jhead;
jhead = p;
else
JCB *q = jhead;
while( (p->worktime > q->worktime) && (q->next!=NULL) )
q = q->next;
if( (p->worktime > q->worktime) && q->next==NULL) //比所有的都大,放到最后
q->next = p;
else if(p->worktime <= q->worktime)
JCB *t = jhead;
while(t->next!=q) //找到前驱节点
t = t->next;
t->next = p;
p->next = q;
void CreateProcess(PCB* &head,PCB* &tail,JCB* &jhead) //创建新进程
PCB* p = new PCB;
p->pname = jhead->jname;
p->state = 'R'; //就绪状态
p->time = jhead->worktime; //进程工作时间
if(tail==NULL)
//就绪队列还是空的,则第一次赋值
head = p;
tail = head;
tail->next = head;
else
//就绪队列不为空
tail->next = p;
tail = p;
p->next = head;
void DropPro(PCB* &head,PCB* &tail,PCB* &chead,PCB* &ctail) //将队首进程,推出循环就绪队列
PCB* p = head; //保存头节点
head = head->next; //头结点指向他的下一个节点
tail->next = head; //将就绪队列尾节点直接指向新的头节点
p->next = NULL; //将分离出来的原来的头节点的next设为空NULL
if(ctail==NULL)
//已完成进程队列还是空的,则第一次赋值
chead = p;
ctail = chead;
else
//已完成进程队列不为空,则将当前已完成进程放到队列尾部
ctail->next = p;
ctail = ctail->next;
void Work(PCB* now) //当前进程执行
now->time--;
void NextPro(PCB* &head,PCB* &tail) //当前进程已执行了一个时间片,将其置于循环队列尾端。即将head和tail向前推进一次
head = head->next;
tail = tail->next;
void printRQ(PCB* head,int readynum) //打印当前就绪队列
PCB* p = head;
printf("\\t--- 就绪队列 ---\\n");
printf("进程名\\t");
printf("所需时间\\t");
printf("进程状态\\n");
if(readynum==0)
//就绪队列已空
printf("空\\n");
return ;
while(p->next!=head)
printf("%d\\t",p->pname);
printf("%d\\t\\t",p->time);
printf("%c\\n",p->state);
p = p->next;
printf("%d\\t",p->pname);
printf("%d\\t\\t",p->time);
printf("%c\\n",p->state);
void printCQ(PCB* chead,PCB* ctail) //打印当前已完成进程队列
PCB* p = chead;
printf("\\t--- 已完成进程 ---\\n");
printf("进程名\\t");;
printf("进程状态\\n");
if(chead==NULL)
//已完成进程队列队列已空
printf("空\\n");
return ;
while(p!=ctail)
printf("%d\\t",p->pname);
printf("%c\\n",p->state);
p = p->next;
printf("%d\\t",p->pname);
printf("%c\\n",p->state);
void printJQ(JCB* jhead) //打印当前后备队列
JCB * p = jhead;
printf("\\t--- 后备队列 ---\\n");
printf("作业名\\t");
printf("到达时间\\t");
printf("工作时间\\n");
if(jhead==NULL)
printf("空\\n");
return ;
while(p->next!=NULL)
printf("%d\\t",p->jname);
printf("%d\\t\\t",p->start);
printf("%d\\n",p->worktime);
p = p->next;
printf("%d\\t",p->jname);
printf("%d\\t\\t",p->start);
printf("%d\\n",p->worktime);
void printProInfo(PCB* now) //打印当前进程信息
if(now==NULL)
printf("当前没有进程\\n");
return ;
printf("\\t--- 运行队列 ---\\n");
printf("进程名:\\t");
printf("运行时间:\\t");
printf("进程状态:\\n");
printf("%d\\t",now->pname);
printf("%d\\t\\t",now->time);
printf("%c\\n",now->state);
void printAllJobInfo(JCB* jhead) //输出作业调度表
JCB* p = jhead->next;
printf("\\t--- 作业调度表 ---\\n");
printf("作业名\\t");
printf("到达时间\\t");
printf("工作时间\\n");
while(p!=NULL)
printf("%d\\t",p->jname);
printf("%d\\t\\t",p->start);
printf("%d\\n",p->worktime);
p = p->next;
int main()
PCB *head=NULL,*tail=NULL; //就绪队列
JCB *jhead=NULL; //后备队列
PCB *chead=NULL,*ctail=NULL; //已完成进程队列
JCB *jobtable = new JCB; //作业调度表
int tablenum=5; //作业调度表中作业数量
int houbeinum=0; //后备队列的作业数量
int readynum=0; //就绪队列的作业数量
jobtable->next = NULL;
for(int i=1; i<6; i++)
CreateJob(jobtable,i);
printAllJobInfo(jobtable); //输出作业调度表
printf("\\t---开始时间片轮转---\\n");
printf("********************************\\n");
int curtime=0;
while(readynum!=0 || houbeinum!=0 || tablenum!=0) //直到就绪队列为空 且 后备队列为空 且 作业调度表为空,退出循环
printf("当前系统时间为%d\\n",curtime);
JCB* p = jobtable->next;
while(p!=NULL)
if(p->start==curtime) //有作业到达,将作业放入后备队列,并按短作业优先放置
JCB *t = p->next;
printf("将作业%d投入到后备队列\\n",p->jname);
AddHoubei(jobtable,p,jhead);
printAllJobInfo(jobtable); //输出调度表
printJQ(jhead); //输出后备队列
houbeinum++; //后备队列
tablenum--; //作业调度表
p = t;
else
p = p->next;
//
//
if(readynum==3) //已满
printJQ(jhead); //输出后备队列
printRQ(head,readynum); //输出就绪队列
else //未满,从后备队列中将作业放入就绪队列
if(houbeinum!=0&&readynum<3) //后备队列不为空并且就绪队列不满
CreateProcess(head,tail,jhead); //将作业投入到就绪队列
printf("将作业%d投入到就绪队列\\n",jhead->jname);
jhead = jhead->next; //指向后备队列下一个作业
readynum++; //就绪队列
houbeinum--; //后备队列
printJQ(jhead); //输出后备队列
printRQ(head,readynum); //输出就绪队列
//已空就算了
PCB* now = head;
if(now!=NULL) //当前就绪队列不为空时运行进程
//将该进程放入运行队列
//rhead = now;
printf("将%d进程放入运行队列\\n",now->pname);
printProInfo(now);
Work(now); //执行当前进程
if(now->time==0)
now->state = 'C'; //设置进程为已完成状态
printf("# 进程%d已完成,退出就绪队列\\n",now->pname);
DropPro(head,tail,chead,ctail); //推出循环就绪队列
printCQ(chead,ctail);
readynum--;
if(readynum==0)
head = 0;
tail = 0;
else
NextPro(head,tail); //已完成,将其置于循环队列尾端。即将head和tail向前推进一次
curtime++;
printf("--------------------------------\\n");
printf("********************************\\n");
return 0;
以上是关于操作系统之处理机调度的主要内容,如果未能解决你的问题,请参考以下文章