实验一: 进程状态转换及PCB的模拟
2019-07-14 07:30 发布
生成海报
实验目的 1)加深对进程概念的理解。 2)深入了解进程控制块和进程状态之间的转换。 3)掌握进程调度算法。 实验预备知识 1)进程的状态 2)进程的结构——PCB 进程都是由一系列操作(动作)所组成,通过这些操作来完成其任务。因此,不同的进程,其内部操作也不相同。在操作系统中,描述一个进程除了需要程序和私有数据之外,最主要的是需要一个与动态过程相联系的数据结构,该数据结构用来描述进程的外部特性(名字、状态等)以及与其它进程的联系(通信关系)等信息,该数据结构称为进程控制块(PCB,Process Control Block)。 进程控制块PCB与进程一一对应,PCB中记录了系统所需的全部信息、用于描述进程情况所需的全部信息和控制进程运行所需的全部信息。因此,系统可以通过进程的PCB来对进程进行管理。 实验步骤 1)设计一个有 N个进程共行的进程调度程序。 2)进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)。每个进程有一个进程控制块( PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。进程的到达时间为进程输入的时间。进程的运行时间以时间片为单位进行计算。每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或阻塞F(Finish)三种状态之一。就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB,以便进行检查。 3)重复以上过程,直到所要进程都完成为止。 调度算法的流程图如下 : 实验结论 1)给出实验源程序(附有详细注释) 2)程序运行截图 #include
#include
typedef struct pcb
{
int name; // 进程的名称
char state;// 进程的状态
int arrivetime; //进程的到达时间
int runtime;// 进程的执行时间
int cputime;//cpu占用的时间
int count;//优先数
struct pcb *next;
}pcb;
pcb *head = NULL; // 正常对列
pcb *head1 = NULL; // 未到达的对列
int n = 0;// 进程的数量
//创建头指针
void createhead()
{
pcb *p = (pcb*)malloc(sizeof(pcb));// 创建头指针
head = p;
pcb *q = (pcb*)malloc(sizeof(pcb));// 创建头指针
head1 = q;
}
void sort()// 按照优先数进行排序
{
pcb* t = head;
pcb *q,*p,*r;
int max;
while(t->next != NULL)
{
p = t->next;
r = t->next;
max = r->count;
while(r!= NULL)
{
if(r->count > max)
{
max = r->count;
p = r;
}
r = r->next;
}// p指向count最大的那一个数
q = t;
while (q->next != p)
q = q->next;
if(t->next != p)
{
q->next = p->next;
p->next = t->next;
t->next = p;
}// 插入进行排序按照优先数
t = t->next;
}
}
bool create() //创建pcb操作
{
createhead();
pcb *p = head;
pcb *q = head1;
printf("请输入进程数目:");
scanf("%d",&n);
pcb *temp;
for(int i=1;i<=n;i++ )//尾插法建立就绪队列
{
temp = (pcb*)malloc(sizeof(pcb));
if(!temp) return false;
printf("请输入进程%d的要求运行时间,进程优先数,到达时间:",i);
scanf("%d %d %d",&(temp->runtime),&(temp->count),&(temp->arrivetime));
temp->cputime = 0;
temp->name=i;
temp->next = NULL;
temp->state='W';
if(temp->arrivetime!=0) // 对到达时间进行判断
{
q->next = temp;
q = temp;
}
else
{
p->next = temp;
p = temp;
}
}
sort(); // 排序
return true;
}
void destory(pcb *rp)// 撤销操作
{
printf("****************进程%d已完成****************
",rp->name);
pcb *q = rp->next;
head->next = q;
free(rp);
}
void display(pcb *rp) // 展示当前的信息
{
printf("进程名字:%d",rp->name);
printf("
进程优先级:%d",rp->count);
printf("
进程所占时间片:%d",rp->runtime);
printf("
进程已运行时间:%d",rp->cputime);
printf("
进程当前状态:%c",rp->state);
printf("
=====================================
");
}
void arrivetime()// 对于到达时间-1的操作
{
pcb *q = head1->next;
pcb *r,*t;
while(q!=NULL) // 判断到达时间是否为0 此时是否到达
{
q->arrivetime--;
if(q->arrivetime==0)
{
t = head1;
while(t->next!=q)
t = t->next;
t->next = q->next;
r = head->next;
q->next = r;
head->next = q;
}
q = q->next;
}
}
void runpcb(pcb *rp)
{
rp->cputime++; //修改cpu占用的时间
arrivetime();
printf("----------正在运行的进程----------
"); // 输出正在运行的队列
display(rp);
if(rp->cputime==rp->runtime)
{
destory(rp);
}
else
{
rp->count--;
rp->state = 'W';
}
pcb *p = head;
if(head->next==NULL&&head1->next==NULL) return;
printf("----------处于就绪对列的进程----------
"); // 输出就绪的队列
while(p->next!=NULL)
{
display(p->next);
p = p->next;
}
pcb *q = head1;
while(q->next!=NULL)
{
display(q->next);
q = q->next;
}
sort();
}
int main()
{
create();// 创造进程
pcb * p;
while(head->next!=NULL || head1->next!=NULL) // 判断两个对列的进程是否都走完
{
if(head->next!=NULL)
{
p= head->next;
p->state='R';
runpcb(p);
}
else
{
arrivetime();
}
}
return 0;
}
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮