实验一 处理器调度
一、实验目的与要求
本实验目的是模拟在单处理器情况下处理器调度,加深了解处理器调度的工作。
要求是从优先级调度和时间片轮转法调度算法中选取一个进行实验。
二、程序中使用的数据结构及符号说明
假设系统中有五个进程,用PCB结构体表示,如表1所示。
表1、PCB结构体
这5个进程都存访在一个数组中。PCB结构体自带next指针,所以PCB结构体自带头指针、用链表实现的队列结构,队列头指针为head。PCB的name表示进程名,假设五个进程的进程名分别是P1,P2,P3,P4,P5。reqtime表示要求运行时间。rank表示优先级,调度时总是选取优先数大的进程先执行。state表示状态,可假设有两种状态,“就绪”状态和“结束”状态,五个进程的初始状态都为“就绪”状态,用“R”表示,当一个进程运行结束后,它的状态变为“结束”,用“E”表示。
在对PCB指针进行比较时需要比较其优先级大小,也需要比较剩余运行时间。
利用cnt变量进行计数,记录当前有几个变量没有运行结束。
三、流程图
四、实验测试结果及结果分析
分析:初始化输入P1进程,优先级为1,要求运行时间为2;P2进程,优先级为5,要求运行时间为3;P3进程,优先级为3,要求运行时间为1;P4进程,优先级为4,要求运行时间为2;P5进程,优先级为2,要求运行时间为4。将五个进程的状态均设为R状态。
在对各进程初始化并连接成队列后,队头指针指向的第一个进程为优先级最大的是P2,第二个是P4,第三个是P3,第四个是P5,第五个是P1。
初始化时选择优先级最高的P2进程先运行,将其优先级和运行时间-1,在运行后将其重新放入队列。
因为P2的优先级仍是最大的,所以继续运行进程P2。在运行后将其插入队列,并按优先级重新排列。
此时优先级最高的P4进程,运行P4,将其优先级和时间-1,在运行后将其插入队列。
此时优先级最高的仍是P4进程,运行P4,优先级和时间-1之后,检测到P4运行时间为0,故结束进程,将其状态置为E,并退出队列。
剩下的进程中P2进程优先级最大,运行P2,将其优先级、时间减1,剩余时间为0,将其退出队列,状态设为E。
剩余进程中P3优先级最高,运行P3,将其优先级和时间-1,剩余时间为0,结束进程,退出队列,状态置为E。
剩下的进程中P5进程优先数最大,将其运行一次后没有运行完成,运行第二次后仍然没有运行完成,且优先数小于另一个剩下的进程P1进程。
P1进程优先级最大,将其运行一次后优先级仍然最大,将其运行第二次后运行完成,置状态为“E”,退出队列。
队列中只剩下一个进程P5进程,将其剩余的时间运行完。由于实验指导书并未规定优先数是否允许为负数,这里每次运行完成时仍然扣除优先级并可以将优先级扣成负数。P5进程运行完成后,所有进程运行完成,按照流程图,处理机结束运行。
五、实验小结
在一个按优先数调度算法实现处理器调度的进程中,各个进程块按照优先级大小有序排列在队列中,并根据优先级前后依次运行,每运行完一个进程后,又重新按照优先级进行排序,选取最高优先级进程运行。直到当该进程的系统要求运行时间为0时,才将其退出队列,状态置为结束。
附件:含比较详细注释说明的源程序清单
下面是用C++编写的源程序代码:
#include<iostream>
#include<iomanip>
#include<string>
#include<algorithm>
#define N 5 //五个进程块
using namespace std;
class PCB { //进程块
public:
PCB* next;//指针
string name;//进程名
int reqtime;//要求运行时间
int rank;//优先级
char state;//状态 R表示就绪 E表示结束
};
PCB* head;
int cnt = 0;
PCB* runningprocess;
PCB P[N];
bool cmprank(PCB a, PCB b) //比较优先级
{
return a.rank > b.rank;
}
void print(PCB* pcb) //显示打印
{
cout << "\nprocess name " << pcb->name << endl;
cout << "remaining running time " << pcb->reqtime << endl;
cout << "priority rank: " << pcb->rank << endl;
cout << "status: " << pcb->state << endl;
}
bool cmpreqtime(PCB a, PCB b)
{
return a.reqtime > b.reqtime;
}
void run(PCB* head, PCB* runningprocess)
{
if (cnt == 0)
{
cout << "\n******every pcb ends******\n";
return;
}
cout << "\n#########process" << runningprocess->name << "running########\n";
runningprocess->rank--; //优先级-1
runningprocess->reqtime--; //要求运行时间-1
cout << "---------every pcb status----------";
for (int i = 0; i < cnt; i++)//显示已就绪进程
{
print(&head[i]); //选队首进程运行
}
cout << "\n--------------------------------\n";
if (runningprocess->reqtime == 0) //某个进程运行结束
{
runningprocess->state = 'E';
print(runningprocess);
sort(head, head + cnt, cmpreqtime);//按照进程剩余时间排序,使结束的进程排在队尾
cnt--;
}
sort(head, head + cnt, cmprank);//按照进程优先级排序
for (int i = 1; i < cnt; i++)
{
head[i - 1].next = &head[i]; //改变指针位置,当一个进程运行结束后退出队列
}
runningprocess = head;//下一次运行的进程为队首进程
run(head, runningprocess);
}
void init() {
head = NULL; //进程队列队首
runningprocess = NULL; //正在运行的程序
cnt = 0; //进程数
}
void input() {
for (int i = 0; i < N; i++)
{
cout << "\nplease input the " << i + 1 << "th process name :\n";
cin >> P[i].name;
cout << "\nplease input the rank of the process\n ";
cin >> P[i].rank;
cout << "\nplease input the reqtime of the process\n ";
cin >> P[i].reqtime;
P[i].state = 'R';
P[i].next = NULL;
cnt++;
}
}
int main()
{
init();
input();
sort(P, P + cnt, cmprank);
for (int i = 1; i < cnt; i++)
{
P[i - 1].next = &P[i];
}
head = &P[0];
runningprocess = &P[0];
cout << "\-------------every pcb initial status--------------\n";
for (int i = 0; i < cnt; i++)
{
print(&P[i]);
}
cout << "\n-----------------------------------------------------";
run(head, runningprocess);
system("pause");
return 0;
}