#include <conio.h>
#include <windows.h>
#include<iostream>
using namespace std;
struct pcb { // 定义进程控制块PCB
char name[10]; // 进程名
char state; // 进程状态
int super; // 优先数
int ntime; // 需要运行时间
int rtime; // 已运行时间
struct pcb* link; // 链接到下一个PCB的指针
}*ready = NULL, *p; // ready为就绪队列头指针
typedef struct pcb PCB;
void insert() // 根据优先级将新创建的PCB(p)插入就绪队列
{
PCB *first, *second;
BOOL bInsert = FALSE;
// 就绪队列为空或者p的优先级大于队首进程的优先级,则将p插入队首
if((ready == NULL)||((p->super) > (ready->super)))
{
p->link = ready;
ready = p;
}
else // 比较进程优先级, 将p插入适当的位置中
{
first = ready;
second = first->link;
while(second != NULL)
{
if((p->super) > (second->super)) // 若插入进程比当前进程优先数大
{ // 插入到当前进程前面
p->link = second;
first->link = p;
second = NULL;
bInsert = TRUE;
}
else // 继续比较
{
first = first->link; // first始终指向second的前一个结点
second = second->link;
}
}
// 插入进程优先数最低,则插入到队尾
if(!bInsert) first->link = p;
}
}
void input() // 创建进程函数
{
int i,num;
system("cls"); // 执行清屏命令
cout << "\n 请输入进程数:";
cin >> num;
for(i = 0; i < num; i++)
{
cout << "\n 进程号No." << i << ":\n";
p = new PCB; // p为全局变量
cout << "\n 输入进程名:";
cin >> p->name;
cout << "\n 输入进程优先数:";
cin >> p->super;
cout << "\n 输入进程运行时间:";
cin >> p->ntime;
cout << endl;
p->rtime = 0; // 新建进程已运行时间为0
p->state = 'w'; // 置就绪状态
p->link = NULL; // 在插入进就绪队列前link无用
insert(); // 根据优先级将p插入就绪队列
}
}
int length() // 用于获取就绪队列长度
{
int l = 0;
PCB* pr = ready;
while(pr != NULL)
{
l++;
pr = pr->link;
}
return(l);
}
void disp(PCB * pr) // 输出当前进程状态,即输出其PCB中信息
{
cout << "\n进程名\t状态\t优先级\t需要运行时间\t已运行时间 \n";
cout << " " << pr->name << "\t ";
cout << pr->state << "\t ";
cout << pr->super << "\t ";
cout << pr->ntime << "\t\t ";
cout << pr->rtime << "\t\n";
}
void check() // 建立进程查看函数
{
PCB* pr;
cout << "\n **** 当前正在运行的进程是:" << p->name; // 显示当前运行进程的名称
disp(p); // 输出当前执行进程信息
pr = ready;
cout << "\n ****当前就绪队列状态为:\n";
// 显示就绪队列中各进程状态
while(pr != NULL)
{
disp(pr);
pr = pr->link;
}
}
void destroy() // 进程运行结束,撤消进程)
{
cout << "\n 进程 ["<<p->name<<"] 已完成.\n";
free(p);
}
void afterRunning() // 当前执行进程时间片到,如未完成置就绪状态,否则撤销进程
{
(p->rtime)++; // 已运行时间加1(以时间片为单位)
if(p->rtime == p->ntime) // 如果已运行时间等于需要运行时间,则撤销进程
destroy(); // 撤销进程
else
{
(p->super)--; // 优先数减1
p->state = 'w'; // 置就绪状态
insert(); // 根据优先级插入就绪队列
}
}
void main() /*主函数*/
{
int len,h = 0; // len为进程数,也即初始状态就绪队列长度;h为时间片编号
char ch;
input();
len = length();
while((len != 0) && (ready != NULL))
{
h++;
cout << "\n 执行时间片:" << h <<endl;
// 从就绪队列摘下队首进程,调度执行
p = ready;
ready = p->link;
p->link = NULL;
p->state = 'R'; // 将当前执行进程置运行状态
check(); // 根据要求,每次调度后显示所有进程信息
afterRunning(); // 当前进程执行一个时间片后的相关工作
cout << "\n 按任一键继续......";
ch = getch(); // 按任一键后进行下一次调度
}
cout << "\n\n 所有进程已经完成.\n";
ch = getch();
}
评论0