1、选题及题目要求
设计一个按时间片轮转法实现处理器调度的程序
(1) 假定系统有5个进程,每个进程用一个PCB来代表。PCB的结构为:
1、进程名——如Q1~Q5。
2、指针——把5个进程连成队列,用指针指出下一个进程PCB的首地址。
3、要求运行时间——假设进程需要运行的时间单位数。
4、已运行时间——进程已运行的时间单位数,初始值为0。
5、状态——假设两种状态,就绪和结束,用R表示就绪,用E表示结束。初始状态都为就绪状态。
(2) 运行之前,为每个进程确定它的“要求运行时间”。通过键盘输入这些参数。
(3) 把5个进程按顺序排成循环队列,用指针指出队列连接情况。用一个标志单元记录轮到运行的进程。处理器调度总是选择标志单元指示的进程运行,对所指的进程,将其“已运行时间”加1。
(4) 进程运行一次后,若“要求运行时间”等于“已运行时间”,则将状态改为“结束”,退出队列,否则将继续轮转。
(5) 若就绪队列为空,结束,否则转到(3)重复。
要求能接受键盘输入的进程要求运行时间,能显示每次进程调度的情况,如哪个进程在运行,哪些进程就绪,就绪进程的排列情况。
2、数据结构设计
根据题目要求,设计了一组指针结构的数据,用于存储每一个进程。
typedef struct node
{
int process_num; //进程名(数字)
struct node *next; //下一进程地址指针
int required_time; //要求运行时间
int processed_time; //已运行时间
bool status; //当前状态,0为就绪,1为结束
}pcb_node;
在程序开始时,通过 create_pcb() 函数来动态链接五个进程,使指针结构首尾相连,然后在 input_pcb() 函数中初始化函数数据,依次输入进程要求运行时间,并存储。
3、程序主要思路和原理
主要思路:利用指针结构连接成循环链表,并且采用头指针(前置一位的指针)的思路,每一步修改当前指针的下一指针结构的内容,以避免在运算过程中需要改变循环结构时(即某一进程完成后将其从循环队列中剔除)的问题。
时间片默认为1,每一次操作将 required_time 减1,processed_time加1,随后检测当前进程是否完成,若完成则将其退出队列,当前指针连接至下下一个指针;若没有完成则将指针指向下一个。
原理:循环链表,指针
4、程序运行结果
任意输入一组时间数据,运行结果如下:
可见,未出现程序错误,且调度结果正常,该实验完成。
5、详细代码
#include <iostream>
using namespace std;
typedef struct node
{
int process_num; //进程名(数字)
struct node *next; //下一进程地址指针
int required_time; //要求运行时间
int processed_time; //已运行时间
bool status; //当前状态,0为就绪,1为结束
}pcb_node;
void create_pcb(pcb_node *first, pcb_node *second, pcb_node *third, pcb_node *fourth, pcb_node *fifth)
{
//按照要求初始化 pcb
first->next = second;
first->process_num = 1;
first->processed_time = 0;
first->status = 0;
second->next = third;
second->process_num = 2;
second->processed_time = 0;
second->status = 0;
third->next = fourth;
third->process_num = 3;
third->processed_time = 0;
third->status = 0;
fourth->next = fifth;
fourth->process_num = 4;
fourth->processed_time = 0;
fourth->status = 0;
fifth->next = first; //构成循环队列
fifth->process_num = 5;
fifth->processed_time = 0;
fifth->status = 0;
}
void input_pcb(pcb_node *first) //输入每个进程的要求运行时间
{
pcb_node *temp = new pcb_node();
temp = first;
int i,time;
cout<<"***************输入要求运行时间***************"<<endl;
for(i=1;i<=5;i++)
{
cout<<endl<<"请输入第"<<i<<"个进程的要求运行时间:";
cin>>time;
temp->required_time = time;
temp = temp->next;
}
}
void run_pcb(pcb_node *first)
{
pcb_node *temp = new pcb_node();
temp->next = first;
cout<<endl<<"*******************进程调度*******************";
int i;
for(i=1;i<=50;i++) //显示每一次进程调度的情况
{
cout<<endl<<endl<<"**程序第"<<i<<"次调度**";
cout<<endl<<"当前进程:Q"<<temp->next->process_num;
cout<<endl<<"就绪进程:";
pcb_node *check = new pcb_node();
check = temp->next;
int ready_num = 0;
while(check->next != temp->next) //按序输出就绪进程队列
{
check = check->next;
if(check->status == 0)
{
cout<<"Q"<<check->process_num<<";";
ready_num = ready_num + 1;
}
}
if(ready_num == 0 && temp->next->status == 0) //针对只剩下一个进程的情况
{
cout<<"当前无就绪进程";
int j;
for(j=1;j<temp->next->required_time;j++)
{
cout<<endl<<endl<<"**程序第"<<i+j<<"次调度**";
cout<<endl<<"当前运行进程:Q"<<temp->next->process_num;
}
cout<<endl<<endl<<"*****************全部调度完成*****************"<<endl;
break;
}
temp->next->required_time --;
temp->next->processed_time ++;
if(temp->next->required_time == 0) //退出进程
{
if(i == 1) //针对第一次调度去掉Q1的情况
{
temp->next->next->next->next->next->next = temp->next->next;
}
temp->next->status = 1;
cout<<endl<<"Q"<<temp->next->process_num<<"进程结束,退出队列";
cout<<endl<<"该进程的运行时间为:"<<temp->next->processed_time;
temp->next = temp->next->next;
continue;
}
temp = temp->next;
}
}
int main()
{
pcb_node *first = new pcb_node();
pcb_node *second = new pcb_node();
pcb_node *third = new pcb_node();
pcb_node *fourth = new pcb_node();
pcb_node *fifth = new pcb_node(); //固定创立五个进程指针
cout<<"说明:共有五个进程,按照时间片轮转算法进行调度运算,下面进行初始化。"<<endl<<endl;
create_pcb(first, second, third, fourth, fifth);
input_pcb(first);
run_pcb(first);
system("pause");
return 0;
}
注:水平较菜,可能存在代码不简洁的部分,但是代码实测是可以跑的,仅供思路参考~