目录
问题描述
设进程优先级 RQ 分为 RQ1、RQ2 和 RQ3;
RQ1>RQ2>RQ3 (优先级:1>2>3);
RQ1 队列:采用轮转法,时间片 q=4;
每个进程最多可连续轮 2 次;
RQ2 队列:采用轮转法,时间片 q=8;
每个进程只能轮转 1 次;
RQ3 队列:采用
短进程(还有多久结束)
优先调度,每个进程运行直至
结束。
![](https://i-blog.csdnimg.cn/blog_migrate/a71094ce01298f12c31061757bfaa467.png)
实现描述:
typedef struct tag_pcb
{ char name[8];
int need;//需运行的时间
int turn;//周转时间
struct tag_pcb *next;
} PCB;
PCB * RQ1,*RQ2,*RQ3,*Finish;
int clock=0; //时钟
main ( )
{ 输入 RQ1;
输入 RQ2;
(最好从文件读入)
while(条件?每个进程最多轮转 2 次)
{
从 RQ1 中选取一进程 Pi 准备运行;
记录其本次实际运行的时间 t(不超过时间片);
clock+=t; //表示 Pi 运行 t;
if (Pi 完成) 计算其 turn;
否则
下一次轮转
或
Pi 加入到 RQ2 队尾
?;
}
while(条件?)
{
从 RQ2 中选取一进程 Pi 准备运行;
记录其本次实际运行的时间 t(不超过时间片)
clock+=t;
if (Pi 完成) 计算其 turn;
否则
Pi 加入到 RQ3 队尾
?
}
while(条件?)
{
从 RQ3 中选取一进程 Pi 准备运行;
记录其本次实际运行的时间 t;
clock+=t;
计算 Pi 的 turn;
}
输出每个进程的周转时间;
}
功能描述
结构体PCB表示进程。RQ1,RQ2,RQ3具有 优先级的就绪队列。
优先级高的进程先执行,进程运行一个时间片后,没有运行完则加入到下一级队列尾,时间片增加一倍。(RQ1中Pi运行结束后加入 RQ2队尾)
若需要运行时间小于轮转时间,进行短进程优先调度。
(RQ2中Pi运行结束后加入RQ3队尾,不再轮转)
计算周转时间:等待时间
(clock)
+运行时间
(min{需要运行时间,时间片长度})
代码实现
在两次轮转中进行操作:RQ1->RQ2,RQ2->RQ3,轮转到的进程需要时间小于一个时间片的时间,则执行完成 ;或者,进程运行一个时间片,然后需要运行时间 -= 时间片长度。写成一个函数:
轮转法:RR(PCB*& rq,PCB*& rq1, int span,int &clock)
//轮转rq队列,符合条件的进程加入rq1队尾。span为时间片长度。传入clock进行计算周转时间,然后还要返回clock的值。
void Insert(PCB*& rq, PCB*& a)//在进程序列rq最后插入一个进程a
{
PCB* q = rq;
while (q->next != NULL) q = q->next;//结尾处
PCB* temp = new PCB;//复制
temp->name = a->name; temp->need = a->need;
temp->turn = a->turn; temp->count = a->count;
temp->next = NULL;
q->next = temp;
}
void RR(PCB*& rq,PCB*& rq1, int span,int &clock)
{
while (rq->next != NULL)
{
PCB* p = rq->next;
int isFinish = 0;
if (p->need <= span)
{
clock += p->need;
isFinish = 1;
p->count--;
}
else//need>span
{
clock += span;
p->need -= span;
p->count--;
}
p->turn += clock;//更改周转时间
//输出
if (isFinish == 1)
{
cout << p->name << ":完成,周转时间为:" << p->turn << endl;
finish.push_back(p);
}
else
{
cout << p->name << ":未完成,周转时间为:" << p->turn << endl;
//没结束移到队列最后面
Insert(rq1, p);
}
if (p->next == NULL)break;
rq->next = p->next;
delete p;
}
}
然后进行短进程优先调度:每次选出队列中需要运行时间最短的进程->运行进程->进程完成,直到队列为空。
短进程:int minTime(PCB*& rq, PCB*& t) //选出最短,用t返回,返回值-1表示队列空。
void SPPSM(int clock) //将选出的进程运行完,clock计算周转时间。
int minTime(PCB*& rq, PCB*& t)//找到队列中需要运行时间最小的一个进程
{
if (rq->next == NULL)
{
t = NULL;
return -1;
}
PCB* pre = rq;
PCB* p = rq->next, * q = NULL;
int min = 100;
while (p!=NULL)
{
if (p->need < min)
{
q = pre;//指向最小的前一个
min = p->need;
}
p = p->next;
pre = pre->next;
}
if (q == NULL)return -1;
t = q->next;
if (t->next == NULL)q->next = NULL;
else q->next = q->next->next;
return 1;
}
void SPPSM(int clock)
{
PCB* p = new PCB;
while (minTime(RQ3, p)==1)
{
clock += p->need;
p->need = 0;
p->turn += clock;
cout << p->name << ":完成,周转时间为:" << p->turn << endl;
}
}
其他部分代码:
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
#include<string>
typedef struct tag_pcb
{
string name;
int need;//需要运行时间
int turn;//周转时间 等待和运行时间
int count;//已经轮转次数
struct tag_pcb* next = NULL;
}PCB;
PCB* RQ1 = new PCB, * RQ2 = new PCB, * RQ3 = new PCB;
vector<PCB*> finish;
int span1 = 4, span2 = 8;//时间片长度
void readfile()
{
ifstream ifs("test1.txt");
if(!ifs.is_open())
{
cout << "打开文件失败!" << endl;
return;
}
PCB* current = RQ1;
while (!ifs.eof())
{
PCB* p = new PCB;
ifs >> p->name >> p->need >> p->turn;
p->count = 3;
current->next = p;
current = current->next;
}
ifs.close();
ifstream ifs1("test2.txt", ios::in);
if (!ifs1.is_open())
{
cout << "打开文件失败!" << endl;
return;
}
current = RQ2;
while (!ifs1.eof())
{
PCB* p = new PCB;
ifs1 >> p->name >> p->need >> p->turn;
p->count = 1;
current->next = p;
current = current->next;
}
ifs1.close();
}
int main()
{
//读RQ1 RQ2
readfile();
int clock = 0;//时钟
cout << "----------" << endl;
RR(RQ1,RQ2,span1,clock);
cout << "----------" << endl;
RR(RQ2,RQ3, span2,clock);
PCB* p = RQ3->next;
SPPSM(clock);
cout << endl;
return 0;
}
文件格式为上面表格的转置(Pi need turn)。