进程调度的模拟实现

这篇博客详细介绍了如何实现操作系统中的进程调度,包括初始化就绪队列、创建进程、判断进程是否存在、按时间、优先级和长度排序等功能。通过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;
}

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

  本模拟程序实现对n个进程根据优先权的高低调度的模拟,创建进程描述符PCB,进程的优先权在运行过程中动态改变,每个时间片结束后显示当前各进程的状态。具体要求如下: 用C语言来实现对n个进程采用不同调度算法进程调度。 每个用来标识进程的进程控制块PCB用结构来描述,包括以下字段:  进程标识数 ID。 进程优先数 PRIORITY,并规定优先数越大的进程,其优先权越高。 进程已占用的CPU时间CPUTIME。 进程还需占用的CPU时间NEEDTIME。当进程运行完毕时,NEEDTIME变为0。 进程的阻塞时间STARTBLOCK,表示当进程再运行STARTBLOCK个时间片后,将进入阻塞状态。 进程被阻塞的时间BLOCKTIME,表示已阻塞的进程再等待BLOCKTIME个时间片后,将转换成就绪状态。 进程状态STATE。 队列指针NEXT,用来将PCB排成队列。 优先数改变的原则: 进程在就绪队列中呆一个时间片,优先数加1。 进程每运行一个时间片,优先数减3。 假设在调度前,系统中有5个进程,它们的初始状态如下: ID 0 1 2 3 4 PRIORITY 9 38 30 29 0 CPUTIME 0 0 0 0 0 ALLTIME 3 3 6 3 4 STARTBLOCK 2 -1 -1 -1 -1 BLOCKTIME 3 0 0 0 0 STATE READY READY READY READY READY 为了清楚的观察各进程的调度过程,程序应将每个时间片内的情况显示出来,参照的具体格式如下: RUNNING PROG:i READY-QUEUE:-〉id1-〉id2 BLOCK-QUEUE:-〉id3-〉id4 = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = == = = ID 0 1 2 3 4 PRIORITY P0 P1 P2 P3 P4 CUPTIME C0 C1 C2 C3 C4 ALLTIME A0 A1 A2 A3 A4 STARTBLOCK T0 T1 T2 T3 T4 BLOCKTIME B0 B1 B2 B3 B4 STATE S0 S1 S2 S3 S4
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

疯狂的小强呀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值