进程调度的模拟实现

这篇博客详细介绍了如何实现操作系统中的进程调度,包括初始化就绪队列、创建进程、判断进程是否存在、按时间、优先级和长度排序等功能。通过FCFS、优先级和SPF调度算法,展示了进程调度的过程,并提供了撤销进程和查看当前就绪队列的功能。
摘要由CSDN通过智能技术生成

总体设计

数据结构定义

  • 结构体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;
}

运行截图:
进程创建:
在这里插入图片描述
先来先服务调度算法:
在这里插入图片描述
优先级调度算法:
在这里插入图片描述
最短作业优先算法:
在这里插入图片描述

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯狂的小强呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值