总体设计
数据结构定义
- 结构体PCB:进程ID、优先级、运行状态、到达时间、运行时间、开始运行时间、进程长度等
- 就绪队列:已就绪的进程id,指向下一个进程的指针
- 结构体PCB数组:模拟当前内存大小
函数
Init()——初始化就绪队列;
Create()——进程创建;
isOrNot(int num)——判断进程是否已经创建;
Arrive()——按到达时间对进程进程排序;
FCFScall(Ready r)——FCFS算法实现;
Prioritycall(Ready r)——Priority算法实现;
SPFcall(Ready r)——SPF算法实现;
kill(Ready r)——进程撤销;
display(Ready r)——就绪队列输出函数:
menu(Ready r)——功能选择界面;
功能测试
在菜单中选择执行各功能,从显示出的就绪队列状态,查看操作的正确与否。
详细设计
在本次模拟实验中,我主要写了十个函数。
在Init()中,我主要创建了进程的头结点,方便后面进程的调用和撤销。
在Create()函数中,我主要将要创建的进程的参数填入PCB,并插入到就绪队列中。在Create()函数中我首先进行了一次判断,判断n是否大于100,如果n>100,说明PCB数组已满(即模拟内存已满)就不能再继续创建进程了,反之可以;然后输入要创建的进程id,并根据已定义的一个函数来判断当前id是否已被创建;如果id重复,我们就要重新输入,直至成功为止,然后将填入参数的PCB节点中,即进程创建成功。
isOrNot(int num)主要是判断当前进程的id是否已经存在,在进程输入的时候会多次调用进行判断。
Arrive()函数主要按进程的到达时间对进程进行排序,方便我们找到第一个到达的进程和为其他调度算法的实现提供方便。
FCFScall(Ready r)函数实现了先来先服务的调度算法,在Arrive()函数的排序基础上,将按时间顺序到达的进程插入就绪队列。
Prioritycall(Ready r)函数实现了按优先级调度的算法,在按到达时间排序的基础上对进程进行优先级排序,最后插入到就绪队列。
SPFcall(Ready r)函数实现了短作业优先调度算法,在按到达时间排序的基础上对进程进行按大小进行排序,最后插入到就绪队列中。
kill(Ready r)主要是撤销进程,输入要撤销的进程的id,将进程从就绪队列中移出。
display()函数主要是输出当前就绪队列中的所有就绪队列的信息,我们可以借助这个函数来查看我们对进程的每一次操作是否成功。
menu()是菜单函数,让我们进行功能选择,我们可以从菜单中选择调用上述的任一函数,从而进一步对进程的创建与撤销进行操作。
代码实现:
#include <stdio.h>
#include <stdlib.h>
#include<malloc.h>
///PCB控制块信息
typedef struct PCBnode{
int id;///进程id
int priority;///进程优先级
int status;///进程状态 0:未就绪 1:运行
int ptime;///进程到达时间
int runtime;///进程运行时间
int start;///开始运行时间
int length;///进程大小
}PCB;
///就绪队列
typedef struct ReadyNode *Ready;
struct ReadyNode{
Ready next;///指向下一个进程
PCB data;///已就绪的进程id
};
PCB pcb[100];///结构体PCB数组,模拟当前内存大小
int N=0;///当前已经创建的进程数目
///创建进程:申请PCB,填入进程参数
void Create(){
int num;
///要申请的进程数大于当前系统的内存
if(N>100){
printf("当前内存已满!\n");
return 0;
}
printf("输入要创建的进程的id:");
scanf("%d",&num);
getchar();
while(isOrNot(num)==1){
printf("请重新输入:");
scanf("%d",&num);
getchar();
}
pcb[N].id=num;
printf("输入要创建的进程的优先级:");
scanf("%d",&pcb[N].priority);
getchar();
printf("输入进程到达时间:");
scanf("%d",&pcb[N].ptime);
getchar();
printf("请输入进程大小:");
scanf("%d",&pcb[N].length);
getchar();
printf("输入进程运行时间:");
scanf("%d",&pcb[N].runtime);
getchar();
pcb[N].status=0;
pcb[N].start=pcb[N].ptime;
N++;
printf("创建成功!\n");
return 0;
}
///判断进程是否已创建
int isOrNot(int num){
for(int i=0;i<N;i++){
if(num==pcb[i].id){
printf("该进程已创建!\n");
return 1;
}
}
return 0;
}
///初始化就绪队列
Ready init(){
Ready head;
head=(Ready)malloc(sizeof(struct ReadyNode));
head->next=NULL;
return head;
}
///按到达时间对进程进行排序
void Arrive(){
PCB temp;
for(int i=0;i<N-1;i++){
for(int j=i+1;j<N;j++){
if(pcb[j].ptime<pcb[i].ptime){
temp=pcb[i];
pcb[i]=pcb[j];
pcb[j]=temp;
}
}
}
return 0;
}
///按先来先服务进行调用
void FCFScall(Ready r){
Ready p=r;
if(r==NULL){
printf("当前无可调用进程!\n");
return 0;
}
Arrive();
for(int i=0;i<N;i++){
pcb[i].status=1;
p->next=(Ready)malloc(sizeof(struct ReadyNode));
p->next->data.id=pcb[i].id;
p->next->data.length=pcb[i].length;
p->next->data.priority=pcb[i].priority;
p->next->data.ptime=pcb[i].ptime;
p->next->data.status=pcb[i].status;
p->next->data.runtime=pcb[i].runtime;
if(i==0){
pcb[i].start=pcb[i].ptime;
}else{
pcb[i].start=pcb[i-1].start+pcb[i-1].runtime;
}
p->next->data.start=pcb[i].start;
p->next->next=NULL;
p=p->next;
}
printf("调用成功!\n");
return 0;
}
///按优先级调用
void Prioritycall(Ready r){
int end;
PCB temp;
Ready p=r;
if(r==NULL){
printf("当前无可调用进程!\n");
return 0;
}
Arrive();
pcb[0].start=pcb[0].ptime;
end=pcb[0].start+pcb[0].runtime;
for(int i=1;i<N-1;i++){
for(int j=i+1;j<N;j++){
if(pcb[i].priority<pcb[j].priority&&pcb[j].ptime<=end){
temp=pcb[i];
pcb[i]=pcb[j];
pcb[j]=temp;
}
}
end+=pcb[i].runtime;
}
for(int i=0;i<N;i++){
pcb[i].status=1;
p->next=(Ready)malloc(sizeof(struct ReadyNode));
p->next->data.id=pcb[i].id;
p->next->data.length=pcb[i].length;
p->next->data.priority=pcb[i].priority;
p->next->data.ptime=pcb[i].ptime;
p->next->data.status=pcb[i].status;
p->next->data.runtime=pcb[i].runtime;
if(i==0){
pcb[i].start=pcb[i].ptime;
}else{
pcb[i].start=pcb[i-1].start+pcb[i-1].runtime;
}
p->next->data.start=pcb[i].start;
p->next->next=NULL;
p=p->next;
}
printf("调用成功!\n");
return 0;
}
///按进程大小调用进程
void SPFcall(Ready r){
int min;
int end;
PCB temp;
Ready p=r;
if(r==NULL){
printf("当前无可调用进程!\n");
return 0;
}
Arrive();
pcb[0].start=pcb[0].ptime;
end=pcb[0].start+pcb[0].runtime;
for(int i=1;i<N-1;i++){
for(int j=i+1;j<N;j++){
if(pcb[j].length<pcb[i].length&&pcb[j].ptime<=end){
temp=pcb[i];
pcb[i]=pcb[j];
pcb[j]=temp;
}
}
end+=pcb[i].runtime;
}
for(int i=0;i<N;i++){
pcb[i].status=1;
p->next=(Ready)malloc(sizeof(struct ReadyNode));
p->next->data.id=pcb[i].id;
p->next->data.id=pcb[i].id;
p->next->data.length=pcb[i].length;
p->next->data.priority=pcb[i].priority;
p->next->data.ptime=pcb[i].ptime;
p->next->data.status=pcb[i].status;
p->next->data.runtime=pcb[i].runtime;
if(i==0){
pcb[i].start=pcb[i].ptime;
}else{
pcb[i].start=pcb[i-1].start+pcb[i-1].runtime;
}
p->next->data.start=pcb[i].start;
p->next->next=NULL;
p=p->next;
}
printf("调用成功!\n");
return 0;
}
///显示正在被调用的进程
void display(Ready r){
Ready p=r->next;
if(p==NULL){
printf("当前无正在运行的进程!\n");
return 0;
}
while(p!=NULL){
printf("进程名:%d\t优先级:%d\t进程大小:%d\t到达时间:%d\t开始时间:%d\t运行时间:%d\n",p->data.id,p->data.priority,p->data.length,p->data.ptime,p->data.start,p->data.runtime);
p=p->next;
}
return 0;
}
///撤销进程
void kill(Ready r){
int num;
Ready temp,p=r;
if(p->next==NULL){
printf("当前系统中无可运行的进程!\n");
return 0;
}
printf("请输入要撤销的进程的id:");
scanf("%d",&num);
while(p->next!=NULL){
if(p->next->data.id==num){
for(int i=0;i<N;i++){
if(pcb[i].id==num){
pcb[i].status=0;
}
}
temp=p->next;
p->next=p->next->next;
free(temp);
printf("撤销成功!\n");
return 0;
}
p=p->next;
}
printf("内存中无该进程!\n");
}
void menu(Ready r){
int n;
while(1){
printf("\n***********进程演示系统*************\n");
printf(" 1.创建进程\n");
printf(" 2.撤销进程\n");
printf(" 3.按先来先服务用进程\n");
printf(" 4.按优先级调用进程\n");
printf(" 5.按最短作业优先调用进程\n");
printf(" 6.查看当前已调用的进程\n");
printf(" 7.撤销进程\n");
printf(" 8.退出程序\n");
printf("************************************\n\n");
printf("请输入你的选择(1-8):");
scanf("%d",&n);
switch(n){
case 1:Create();
break;
case 2:kill(r);
break;
case 3:FCFScall(r);
break;
case 4:Prioritycall(r);
break;
case 5:SPFcall(r);
break;
case 6:display(r);
break;
case 7:kill(r);
break;
case 8:return 0;
default:printf("没有这个选项!");
break;
}
}
return 0;
}
int main()
{
Ready r;
r=init();
menu(r);
return 0;
}
运行截图:
进程创建:
先来先服务调度算法:
优先级调度算法:
最短作业优先算法: