操作系统课程设计进程调度模拟

这篇具有很好参考价值的文章主要介绍了操作系统课程设计进程调度模拟。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

程序下载链接:https://download.csdn.net/download/m0_56241309/86945709

进程调度模拟

摘要:进程调度是操作系统中必不可少的一种调度,在3中OS中都无一例外地配置了进程调度。此外,它也是对系统性能影响最大的一种处理机调度,在操作系统中具有十分重要的地位。本次模拟,旨在全方位地了解、掌握、运用各种调度算法,包括从本质上理解各种调度方法的实现方式、各种调度算法使用的数据结构、各种调度方法使用的函数模块、各种调度算法的函数调用情况等等。针对本次模拟,任务中包括了四种在操作系统中较为重要的调度方法,因此最先考虑的是如何依次实现各种调度方法,包括对各种算法的系统功能设计、模块、流程设计、数据结构设计等等。之后再依调整各种算法内部的数据结构以及符号名,消除各个算法之间的冲突,主要是命名冲突引起的函数调用冲突、变量使用冲突。在对各种算法进行调整后,将其整合到一个主体呈现出switch结构的MAIN()函数中。经过本次模拟,总体上较为完整地实现了对N个进程采用4个进程调度算法的目的(四选一),但在各种算法的内部仍然存在许多值得优化的地方,例如在MAIN()函数中涉及一个整体的数据结构即可避免在每一个算法中都对数据结构进行大体上重复的定义,诸如此类的可以优化的地方依然存在,因此本次模拟并不是最终目的,后继学习过程中对操作系统调度算法的更加熟练的掌握将更加有助于我们对于计算机操作系统的理解与掌握。

关键词:操作系统;进程调度;课程设计

1 设计任务

1.1 设计目的

在多道程序环境下,内存中存在许多进程,其数目往往多余处理及的数量。这就要求操作系统能够按照某种算法动态地将处理机分配给处于就绪状态的进程。对于一个大型的操作系统而言,其运行是的性能,诸如系统吞吐量、资源利用率、作业周转时间、响应的及时性等,在很大程度上都取决于处理机调度性能的好坏。如若处理机调度存在问题,则会非常容易导致系统出现死锁,进程将无法向前推进。次模拟选题为进程调度模拟,旨在了解、认识、掌握调度算法这一处理机调度最为核心的部分,实现对多个进程实现不同的调度方法,加深对操作系统调度方法的掌握,进而更加深层次地认识操作系统。

1.2 设计内容

1.2.1设计要求

(1)对N个进程分别采用四种进程调度算法(轮转调度、静态优先级调度、动态优先级调度、最短进程优先调度)执行调度模拟。

(2)每个用来标识进程的进程表项(进程控制块 PCB)可用结构体来描述,包括以下字段(具体字段及数量可根据需要自行定义,此处仅供参考):

(a)进程标识数 ID。

(b) 进程优先数 PRIORITY,并规定优先数越大的进程,其优先权越高。

(c) 进程运行所需CPU总时间片数ALLTIME,已占用 CPU 时间片数 CPUTIME。当进程运行完毕时,ALLTIME 变为 0。

(d) 进程的待阻塞时间片数 STARTBLOCK,表示当进程再运行 STARTBLOCK个时间片后,进程将进入阻塞状态。

(e) 进程被阻塞的时间片数 BLOCKTIME ,表示已阻塞的进程再等待 BLOCKTIME 个时间片后,将转换成就绪状态。

(f) 进程状态 STATE。

(g) 队列指针 NEXT,用来将 PCB 排成队列。

(3)进程数量要求可以指定任意数量,每个进程运行所需的CPU时间数要求可以指定任意数量或随机生成。

(4)静态优先级调度,每个进程的优先级要求可以任意指定或随机生成。

(5)动态优先级调度原则:进程在就绪队列中呆一个时间片,优先数增加 1;进程每运行一个时间片,优先数减 3(这一规则主要用于动态优先级调度算法)。

(6)最短进程优先中的进程长度根据剩余所需CPU时间片数动态计算。

(7)为了观察每个进程的调度过程,程序应将每个时间片内的进程的情况显示出来,包括正在运行的进程,处于就绪队列中的进程和处于阻塞队列中的进程。

(8)要求在linux ubuntu环境下使用c/c++编写。

1.2.2部分调整

(1)本次模拟首先对四种调度方法分别进行了实现,因此各种调度算法内部的PCB数据结构存在着一定程度上的差别,但对于每种调度算法均采用了设计要求中规定的变量名程。

(2)后期对各种调度算法进行整合时,出现了变量命名之间的冲突,因此部分算法内部的变量命名出现了诸如RR(轮转调度)、DP(动态优先级)、SP(静态优先级)、SJF(最短进程优先)字样的前缀。

(3)在本次模拟中,提供了四种调度方法供用户选择,以此实现对N种进程采用4种不同的调度方法。

2 总体设计

2.1 总体结构

操作系统课程设计进程调度模拟

图2-1 模拟进程调度演示系统功能模块图

2.2 开发环境

Linux操作系统、VMware虚拟机、开发语言c/c++、HUAWEI MATEBOOK XPRO笔记本

3 算法设计

3.1轮转调度算法

   在早期的时间片轮转法中,系统将所有的就绪进程按先来先服务的原则,排成一个队列,每次调度时,把CPU分配给队首进程,并令其执行一个时间片。如果就绪队列上存在N个进程,那么每个进程每次大约可获得1/N的处理机时间。

   如图2-1功能模块图所示,在轮转调度方法种,需要对PCB块进行数据结构设计,并且完成对队列结点定义模块、队列初始化模块、进程队列创建模块、进程插入模块、进程输出模块、RR算法模块的实现。

        具体流程如下:(虚线仅代表在程序编写时逻辑上的先后顺序,实现代表模块之间存在调用关系)

操作系统课程设计进程调度模拟

        其中,RR轮转调度算法中设计的PCB数据结构如下:

操作系统课程设计进程调度模拟

3.2静态优先级调度算法

        优先级调度算法中的静态优先级调度在一开始便根据各个进程的PRIORITY确定下来进程的顺序,优先级在整个运行期间保持不变。一般而言,确定进程优先级大小的依据主要有进程类型、进程对资源的需求、用户要求。静态优先级的调度方法简单易行,但不够精确,会出现进程长时间无法被调度的现象。

   如图2-1功能模块图所示,在静态优先级调度算法种,除了对PCB数据块进行设计,还需要完成对进程队列创建模块、SP算法等模块的实现。

        具体流程如下:

操作系统课程设计进程调度模拟

        其中,SP静态优先级调度算法中设计的PCB数据结构如下:

操作系统课程设计进程调度模拟

3.3动态优先级调度算法

      动态优先级调度算法是指在进程创建之初,赋予进程一个暂时的优先级别,随着进程的推进,进程的优先级别会随之改变,本次模拟中采用的规则为: 进程在就绪队列中呆一个时间片,优先数增加 1;进程每运行一个时间片,优先数减 3。这样的调度方法可以较为公平地实现进程间处理机的分配,避免了一个长期进程长期垄断处理机的现象。

   如图2-1功能模块图所示,在动态优先级调度算法中,需对PCB数据块进行设计,此外还需完成对进程队列创建模块、DP算法等模块的实现。

        具体流程如下:

       操作系统课程设计进程调度模拟

其中,DP动态优先级调度算法中设计的PCB数据结构如下:

操作系统课程设计进程调度模拟

3.4最短进程优先调度算法

      最短进程优先调度方法以进程的长短来计算优先级,本次模拟中采用进程所需的CPU时间片数来作为优先级的判定依据,即每个进程的剩余ALLTIME时间数。最短进程优先调度每次从队列中取出时间最短的进程运行。最短进程优先调度算法的缺点在于,必须预先知道进程运行所需时间、对ALLTIME较长的进程并不友好、当采用FCFS调度方法时,无法实现人机交互。此外,最短进程优先调度方法无法考虑到进程的紧急程度,因此无法保证紧急的作业得到及时处理。

    如图2-1功能模块图所示,最短进程优先调度算法中,除对PCB数据块进行设计以外,还需实现进程队列创建模块、调度结果输出模块、SJF算法等模块。

        具体流程如下:

依旧使用数组的形式来存放进程,便于实现依据次序标号对进程的直接查找以及调度

操作系统课程设计进程调度模拟

        其中,SJF最短进程优先调度算法中设计的PCB数据结构如下:

操作系统课程设计进程调度模拟

4 系统实现

4.1 用户输入模块实现(部分主函数的实现)

#include"SJF.h"

#include"SP.h"

#include"RR.h"

#include"DP.h"



int main()

{  

    printf("【本次模拟除进程名以外的所有输入均为整数】\n\n\n");

    int B;

    printf("请选择PRIORITY、ALLTIME的生成方式:\n【1】手动输入\n【2】随机生成\n");

    scanf("%d",&B);

    int A;

    printf("\n");

    printf("请选择调度方法(输入对应序号即可)\n");

    Q:printf("【1】轮转调度\n【2】最短进程优先调度\n【3】静态优先级调度\n【4】动态优先级调度\n");

    scanf("%d",&A);

    if (A>4)

    {

        printf("输入有误,请重新输入\n");

        goto Q;

}

}

4.2 轮转调度模块实现

4.2.1 PCB数据结构设计

typedef struct pcb          //定义进程控制块

{

    char ID[MaxNum];        //进程号

    int Arrive_Time;        //进程到达时间,用以排序

    int ALLTIME;            //进程运行所需总时间

    int WHLOLETIME;         //固定运行时间

    int FinishTime;         //完成时间

    double RUN_AROUND_TIME; //周转时间

    double WeightWholeTime; //带权周转时间

    char STATE;             //进程状态

    struct pcb *NEXT;

}RRPCB;

4.2.2队列结点定义模块

typedef struct   //定义队列以及头结点尾结点

{

    RRPCB *front,*rear;

}queue;

4.2.3队列初始化模块

queue *Init()  //初始化队列

{

    queue *HEAD;

    HEAD=(queue*)malloc(sizeof(queue));

    HEAD->front=NULL;

    HEAD->rear=NULL;

    return HEAD;

}

4.2.4进程队列创建模块

queue *CreatQueue(queue *head,int M,int B)   //创建进程队列

{

    char c[MaxNum];

    char s='R';

    int a,r,i;

    if (B==1)

    {

        for(i=1;i<=M;i++)

        {

        printf("请输入第%d个进程的进程名:\n",i);

        getchar();

        cin.get(c,MaxNum);

        printf("请输入第%d个进程的到达时间:\n",i);

        scanf("%d",&a);

        printf("请输入第%d个进程的服务时间:\n",i);

        scanf("%d",&r);

        head=Insert(head,c,a,r,s);

        printf("\n");

        }

    }

    else

    {

        for(i=1;i<=M;i++)

        {

        printf("请输入第%d个进程的进程名:\n",i);

        getchar();

        cin.get(c,MaxNum);

        printf("请输入第%d个进程的到达时间:\n",i);

        scanf("%d",&a);

        r=(int)(rand()%12);//r即进程所需总时长

        head=Insert(head,c,a,r,s);

        printf("\n");

        }

    }

    return head;

}

4.2.5进程插入模块

queue *Insert(queue *head,char c[MaxNum],int a,int r,char s)  //将进程插入队列,每次取出队首的进程运行

{

    RRPCB *p;

    p=(RRPCB *)malloc(sizeof(RRPCB));

    strcpy(p->ID,c);

    p->Arrive_Time=a;

    p->ALLTIME=r;

    p->WHLOLETIME=r;

    p->STATE=s;

    p->NEXT=NULL;

    if(Empty(head))

        head->front=head->rear=p;

    else

    {

        head->rear->NEXT=p;

        head->rear=p;

    }

    return head;

}

4.2.6进程输出模块

void print(queue *head)  //输出进程

{

    RRPCB *p;

    p=head->front;

    if(!p)

        printf("时间片轮转调度队列为空!\n");

    while(p)

    {

        printf("ID=%s   Arrvie_Time=%d   ALLTIME=%d   STATE=%c",p->ID,p->Arrive_Time,p->ALLTIME,p->STATE);

        printf("\n");

        p=p->NEXT;

    }

}

4.2.7RR(轮转调度)算法模块

void RR(queue *head,int Time_Slice)

{

    int t=head->front->Arrive_Time, lt=head->rear->Arrive_Time;

    if(head->front->ALLTIME<Time_Slice)

        t=t+head->front->ALLTIME;

    else

        t=t+Time_Slice;

    //队列为空则无法调度

    while(!Empty(head))

    {

        RRPCB *p1,*p2;

        printf("\n时刻   进程   状态\n");

        //当前运行的时间小于最后一个进程到达时间

        while(t<lt)

        {

            p1=head->front;

            printf("%2d      %s",t,p1->ID);

            p1->ALLTIME=p1->ALLTIME-Time_Slice;//判断在进程所需要的ALLTIME内是否可以完成,用ALLTIME-CPUTIME判断

            //1.运行时间小于0,删除队首进程

            if(p1->ALLTIME<=0)

            {

                p1->STATE='C';

                printf("       %c\n",p1->STATE);

                p1->FinishTime=t;

                p1->RUN_AROUND_TIME=p1->FinishTime-p1->Arrive_Time;

                p1->WeightWholeTime=p1->RUN_AROUND_TIME/p1->WHLOLETIME;

                SumWT+=p1->RUN_AROUND_TIME;

                SumWWT+=p1->WeightWholeTime;

                printf("=========================================================\n");

                printf("时刻%2d进程%s运行结束,进程%s周转时间=%5.2f,带权周转时间=%5.2f\n",t,p1->ID,p1->ID,p1->RUN_AROUND_TIME,p1->WeightWholeTime);

                printf("=========================================================\n");

                head->front=p1->NEXT;

                free(p1);

            }

            //2.运行时间大于0,继续排队

            else

            {

                printf("        %c\n",p1->STATE);

                p2=p1->NEXT;

                while(p2->NEXT && p2->Arrive_Time != t)

                {

                    p2=p2->NEXT;

                }

                //没有新的进程到达时

                //1.保持队首进程

                //2.队首进程后移

                if(p2->Arrive_Time != t)

                {

                    RRPCB *p3=p1,*p4=NULL;

                    while(p3->NEXT && p3->Arrive_Time<t)

                    {

                        p4=p3;

                        p3=p3->NEXT;

                    }

                    if(p3->Arrive_Time>t)

                    {

                        if(p4!=p1)   //p1插在p4后,头节点p1->NEXT

                        {

                            head->front=p1->NEXT;

                            p1->NEXT=p4->NEXT;

                            p4->NEXT=p1;

                        }

                        else

                            p4=p3=p2=NULL;

                    }

                    else

                        p4=p3=p2=NULL;

                }

                //新的进程到达

                //队首进程插入在新进程之后,指针更新

                else

                {

                    head->front=p1->NEXT;

                    p1->NEXT=p2->NEXT;

                    p2->NEXT=p1;

                }

            }

            //更新时间

            if(head->front->ALLTIME<Time_Slice)

                t=t+head->front->ALLTIME;

            else

                t=t+Time_Slice;

        }

       



        //ALLTIME大于最后一个进程到达的时间

        while(t>=lt)

        {

            p1=head->front;

            printf("%2d      %s",t,p1->ID);

            p1->ALLTIME=p1->ALLTIME-Time_Slice;

            //1.运行时间小于0,删除队首进程

            if(p1->ALLTIME<=0)

            {

                p1->STATE='C';

                printf("       %c\n",p1->STATE);

                p1->FinishTime=t;

                p1->RUN_AROUND_TIME=p1->FinishTime-p1->Arrive_Time;

                p1->WeightWholeTime=p1->RUN_AROUND_TIME/p1->WHLOLETIME;

                SumWT+=p1->RUN_AROUND_TIME;

                SumWWT+=p1->WeightWholeTime;

                printf("=========================================================\n");

                printf("时刻%2d进程%s运行结束,进程%s周转时间=%5.2f,带权周转时间=%5.2f\n",t,p1->ID,p1->ID,p1->RUN_AROUND_TIME,p1->WeightWholeTime);

                printf("=========================================================\n");

                //printf("时刻%2d进程%s运行结束",t,p1->pname);

                head->front=p1->NEXT;

                free(p1);

               

            }

            //2.运行时间大于0,进程插入队列末

            else

            {

                printf("       %c\n",p1->STATE);

                //队列中只有一个进程无需更改

                if(!p1->NEXT)

                    head->front=p1;

                 //队列中的进程数大于1时

                else

                {

                    head->front=p1->NEXT;

                    head->rear->NEXT=p1;

                    head->rear=p1;

                    p1->NEXT=NULL;

                }

            }

            //更新时间

            if(Empty(head))

                return;

            else

            {

                if(head->front->ALLTIME<Time_Slice)

                    t=t+head->front->ALLTIME;

                else

                    t=t+Time_Slice;

            }

        }



        }

    }

4.3 静态优先级调度模块实现

4.3.1PCB数据结构设计模块

struct PCB

{

    char PNAME[20];

    int PRIORITY;

    int ALLTIME;

    int CPUTIME;

    char STATE;

    struct PCB* NEXT;

    int num;

};

4.3.2进程队列创建模块

struct PCB *processes, *Temp_Node;

    //Temp_Node作为临时节点来创建链表

    processes = Temp_Node = (struct PCB*)malloc(sizeof(struct PCB));

    if (B==1)

    {

       for (int i = 1; i <= N; ++i)

        {

        struct PCB *p = (struct PCB*)malloc(sizeof(struct PCB));

        printf("进程号No.%d:\n", i);

        printf("输入进程名:");

        scanf("%s", p->PNAME);

        printf("输入进程优先数:");

        scanf("%d", &p->PRIORITY);

        printf("输入进程所需总时间:");

        scanf("%d", &p->ALLTIME);

        p->CPUTIME = 0;

        p->STATE = 'W';

        p->NEXT = NULL;

        Temp_Node->NEXT = p;

        Temp_Node = p;

        p->num=p->ALLTIME;

        printf("\n\n");

        }

    }

    else

    {

        for (int i = 1; i <= N; ++i)

        {

        struct PCB *p = (struct PCB*)malloc(sizeof(struct PCB));

        printf("进程号No.%d:\n", i);

        printf("输入进程名:");

        scanf("%s", p->PNAME);

        p->PRIORITY=(int)(rand()%12);

        p->ALLTIME=(int)(rand()%12);

        p->num=p->ALLTIME;

        p->CPUTIME = 0;

        p->STATE = 'W';

        p->NEXT = NULL;

        Temp_Node->NEXT = p;

        Temp_Node = p;

        printf("\n\n");

        }

    }

4.3.3SP(静态优先级调度)算法模块

//processes作为头结点来存储链表

    processes = processes->NEXT;

    int Present_Time = 0;

    struct PCB *P_INORDER = processes;

    while (1)

    {  

        ++Present_Time;

        Temp_Node = processes;

        //对链表按照优先数排序

        //P_INORDER用来存放排序后的链表

        P_INORDER = SortList(P_INORDER);

        printf("===============================================\n");

        printf("当前时刻为: %d\n", Present_Time-1);

        printf("===============================================\n");

        printf("当前正在运行的进程是:%s\n", P_INORDER->PNAME);

        P_INORDER->STATE = 'R';

        P_INORDER->num--;

        P_INORDER->CPUTIME++;

        printf("PNAME    STATE    PRIORITY    ALLTIME    CPUTIME\n");

        printf("  %s        %c          %d          %d          %d\n", P_INORDER->PNAME, P_INORDER->STATE, P_INORDER->PRIORITY, P_INORDER->num, P_INORDER->CPUTIME);

        Temp_Node->STATE = 'W';

       

        printf("当前就绪状态的队列为:\n\n");

        //Temp_Node指向已经排序的队列

        Temp_Node = P_INORDER->NEXT;

        while (Temp_Node != NULL)

        {  

            printf("PNAME    STATE    PRIORITY    ALLTIME    CPUTIME\n");

            printf("  %s        %c          %d          %d          %d\n", Temp_Node->PNAME, Temp_Node->STATE, Temp_Node->PRIORITY, Temp_Node->ALLTIME, Temp_Node->CPUTIME);

            Temp_Node = Temp_Node->NEXT;

        }

        //Temp_Node指向已经排序的链表

        Temp_Node = P_INORDER;

        struct PCB *PRE_TEMPNODE;

        PRE_TEMPNODE = NULL; //PRE_TEMPNODE指向Temp_Node的前一个节点

        while (Temp_Node != NULL)

        {

            if (Temp_Node->ALLTIME == Temp_Node->CPUTIME)

            {

                if (PRE_TEMPNODE == NULL)

                {

                    Temp_Node = P_INORDER->NEXT;

                    P_INORDER = Temp_Node;

                }

                else

                    PRE_TEMPNODE->NEXT = Temp_Node->NEXT;

            }

            PRE_TEMPNODE = Temp_Node;

            Temp_Node = Temp_Node->NEXT;

        }

       

    }

}



struct PCB* SortList(PCB* HL)

{

    struct PCB* SL;

    SL = (struct PCB*)malloc(sizeof(struct PCB));

    SL = NULL;



    struct PCB* r = HL;

    while (r != NULL)

    {

        struct PCB* t = r->NEXT;

        struct PCB* cp = SL;

        struct PCB* PRE_TEMPNODE = NULL;

        while (cp != NULL)

        {

            if (r->PRIORITY > cp->PRIORITY)

                break;

            else

            {

                PRE_TEMPNODE = cp;

                cp = cp->NEXT;

            }

        }

        if (PRE_TEMPNODE == NULL)

        {

            r->NEXT = SL;

            SL = r;

        }

        else

        {

            r->NEXT = cp;

            PRE_TEMPNODE->NEXT = r;

        }

        r = t;

    }

    return SL;

4.4 动态优先级调度模块实现

4.4.1PCB数据结构设计模块

typedef struct{

    char ID;

    int PRIORITY;

    int CPUTIME;

    int ALLTIME;

    int STARTBLOCK;

    int BLOCKTIME;

    int STATE;//0-运行 1-阻塞 2-就绪 3-结束 4-未到达

    int Arrive_Time;

    int TIME;

}PROCESS;

4.4.2进程队列创建模块

IntDI=0,DPTime_Slice,max,l,l1,time1,flag=0,total=0,server[10],sum=0,DPN=0;

        PROCESS pro[10];

        cout<<"本程序中状态代表如下"<<endl<<"【0】-运行  【1】-阻塞  【2】-就绪  【3】-结束  【4】-未到达"<<endl<<endl;

        if (B==1)

        {

            cout<<"请输入进程数:";

            cin>>DPN;

            cout<<"请设置时间片长度:";

            cin>>DPTime_Slice;

            cout<<"请输入各进程初始状态:"<<endl;

            cout<<"ID  PRIORITY  Arrive_Time  ALLTIME  STARTBLOCK  BLOCKTIME"<<endl;

            for(DI=0;DI<DPN;DI++)

            {//进程初始化

            pro[DI].CPUTIME=0;

            pro[DI].TIME=0;

            cin>>pro[DI].ID>>pro[DI].PRIORITY>>pro[DI].Arrive_Time;

            cin>>pro[DI].ALLTIME>>pro[DI].STARTBLOCK>>pro[DI].BLOCKTIME;

            server[DI]=pro[DI].ALLTIME;

            if(pro[DI].Arrive_Time==0) pro[DI].STATE=0;

            else pro[DI].STATE=4;

            }

        }

        else

        {

            cout<<"请输入进程数:";

            cin>>DPN;

            cout<<"请设置时间片长度:";

            cin>>DPTime_Slice;

            cout<<"请输入各进程初始状态:"<<endl;

            cout<<"ID   Arrive_Time   STARTBLOCK  BLOCKTIME"<<endl;

            for (int DI = 0; DI < DPN; DI++)

            {

                pro[DI].CPUTIME=0;

                pro[DI].TIME=0;

                cin>>pro[DI].ID>>pro[DI].Arrive_Time;

                cin>>pro[DI].STARTBLOCK>>pro[DI].BLOCKTIME;

                pro[DI].PRIORITY=(int)(rand()%10);

                pro[DI].ALLTIME=(int)(rand()%10);

                server[DI]=pro[DI].ALLTIME;

                if(pro[DI].Arrive_Time==0) pro[DI].STATE=0;

                else pro[DI].STATE=4;

            }

        }

4.4.3DP(动态优先级调度)算法模块

do{

        cout<<endl<<"当前时刻为:"<<total;

        cout<<endl<<"========================各进程状态为======================"<<endl;

        cout<<"ID  PRIORITY  CPUTIME  ALLTIME  STARTBLOCK  BLOCKTIME  STATE"<<endl;

        for(DI=0;DI<DPN;DI++){

            cout<<pro[DI].ID<<"      "<<pro[DI].PRIORITY<<"        "<<pro[DI].CPUTIME<<"        ";

            cout<<pro[DI].ALLTIME<<"         "<<pro[DI].STARTBLOCK<<"           "<<pro[DI].BLOCKTIME<<"         "<<pro[DI].STATE;

            cout<<endl;

        }

       

        total+=DPTime_Slice;

        for(DI=0;DI<DPN;DI++){

            if(pro[DI].STATE==4&&pro[DI].Arrive_Time<total){

                pro[DI].STATE=1;

            }

        }

        for(DI=0;DI<DPN;DI++){

            time1=pro[DI].ALLTIME;

            if(pro[DI].STATE==0){

                if(pro[DI].ALLTIME<=DPTime_Slice){

                    pro[DI].ALLTIME=0;

                    pro[DI].STATE=3;

                    pro[DI].TIME=total-DPTime_Slice+time1;

                }

                else{

                    pro[DI].ALLTIME-=DPTime_Slice;

                    pro[DI].STARTBLOCK--;

                    if(pro[DI].STARTBLOCK==0){

                        pro[DI].STATE=1;

                        pro[DI].BLOCKTIME=time1;

                        pro[DI].STARTBLOCK=time1;

                    }

                    pro[DI].PRIORITY-=3;

                    pro[DI].TIME=total;

                }

            }

            if(pro[DI].STATE==1){

                pro[DI].BLOCKTIME--;

                if(pro[DI].BLOCKTIME==0) pro[DI].STATE=2;

                pro[DI].TIME=total;

            }

            if(pro[DI].STATE==2){

                pro[DI].PRIORITY++;

                pro[DI].TIME=total;

            }

        }

        max=-100;

        l1=-1;

        l=-1;

        for(DI=0;DI<DPN;DI++){

            if(pro[DI].PRIORITY>max&&(pro[DI].STATE==0||pro[DI].STATE==2)){

                l=DI;

                max=pro[DI].PRIORITY;

            }

            if(pro[DI].STATE==0) l1=DI;

        }

        if(l!=-1&&l!=l1) pro[l].STATE=0;

        if(l1!=-1) pro[l1].STATE=2;

        flag=0;

        for(DI=0;DI<DPN;DI++){

            if(pro[DI].STATE!=3){

                flag=1;

                break;

            }

        }

        if(flag==0) break;

        }while(1);

        cout<<endl<<"当前时刻:"<<total;

        cout<<endl<<"========================各进程状态为======================"<<endl;

        cout<<"ID  PRIORITY  CPUTIME  ALLTIME  STARTBLOCK  BLOCKTIME  STATE"<<endl;

        for(DI=0;DI<DPN;DI++){

        cout<<pro[DI].ID<<"      "<<pro[DI].PRIORITY<<"        "<<pro[DI].CPUTIME<<"        ";

        cout<<pro[DI].ALLTIME<<"         "<<pro[DI].STARTBLOCK<<"           "<<pro[DI].BLOCKTIME<<"         "<<pro[DI].STATE;

        cout<<endl;

        }

        cout<<endl<<"各进程运行结束!"<<endl;

        cout<<"进程号  到达时间  结束时间  周转时间  带权周转时间"<<endl;

        for(DI=0;DI<DPN;DI++){

        cout<<"  "<<pro[DI].ID<<"        "<<pro[DI].Arrive_Time<<"         "<<pro[DI].TIME<<"       "<<pro[DI].TIME-pro[DI].Arrive_Time<<"        "<<(float)(pro[DI].TIME-pro[DI].Arrive_Time)/server[DI]<<endl;

        sum+=pro[DI].TIME-pro[DI].Arrive_Time;

        }

        cout<<"平均周转时间为:"<<(float)sum/DPN<<endl;

4.5 最短进程优先调度模块实现

4.5.1PCB数据结构设计模块

 struct Process_struct{

    int  Number;                            //进程编号

    char Name[MaxNum];                      //进程名称

    int  ArrivalTime;                       //到达时间

    int  ServiceTime;                       //开始运行时间

    int  FinishTime;                        //运行结束时间

    int  SJF_ALLTIME;                       //运行时间

    int STATE;                              //调度标志

    int order;                              //运行次序

    double  WeightWholeTime;                //周转时间

    double AverageWT_SJF;                   //平均周转时间

    double AverageWWT_SJF;                  //平均带权周转时间

}Process[MaxNum];

4.5.2进程队列创建模块

int PROCESSinput(int B)         //进程参数输入

{

    int i;

    printf("请输入进程个数:\n");

    scanf("%d",&SJFPN);

    if (B==1)

    {

        for(i=0;i<SJFPN;i++)

        {

        printf("请输入第%d个进程名称:",i+1);

        scanf("%s",Process[i].Name);

        printf("请输入第%d个进程的到达时间:",i+1);

        scanf("%d",&Process[i].ArrivalTime);

        printf("请输入第%d个进程的ALLTIME:",i+1);

        scanf("%d",&Process[i].SJF_ALLTIME);

        Process[i].ServiceTime=0;

        Process[i].FinishTime=0;

        Process[i].WeightWholeTime=0;

        Process[i].order=0;

        Process[i].STATE=0;

        printf("\n");

        }

    }

    else

    {

        for(i=0;i<SJFPN;i++)

        {

        printf("请输入第%d个进程名称:",i+1);

        scanf("%s",Process[i].Name);

        printf("请输入第%d个进程的到达时间:",i+1);

        scanf("%d",&Process[i].ArrivalTime);

        Process[i].SJF_ALLTIME=(int)(rand()%11);

        Process[i].ServiceTime=0;

        Process[i].FinishTime=0;

        Process[i].WeightWholeTime=0;

        Process[i].order=0;

        Process[i].STATE=0;

        printf("\n");

        }

    }

    return 0;

}

4.5.3调度结果输出模块

int OUTCOME()   //调度结果输出

{

    int i;

    float turn_round_time=0,f1,w=0;

    printf("      进程名称 到达时间 运行时间 开始时间 结束时间 执行顺序  周转时间  带权周转时间\n");

    for(i=0;i<SJFPN;i++)

    {

        Process[i].WeightWholeTime=Process[i].FinishTime-Process[i].ArrivalTime;

        f1=Process[i].WeightWholeTime/Process[i].SJF_ALLTIME;

        turn_round_time+=Process[i].WeightWholeTime;

        w+=f1;

        printf("时刻%d :",Process[i].ServiceTime,Process[i].Name);

        printf("   %s       %d       %d         %d         %d         %d        %.2f        %.2f\n",Process[i].Name,Process[i].ArrivalTime,Process[i].SJF_ALLTIME,Process[i].ServiceTime,Process[i].FinishTime,Process[i].order,Process[i].WeightWholeTime,f1);

    }

    printf("平均周转时间=%.2f\n",turn_round_time/SJFPN);

    printf("带权平均周转时间=%.2f\n",w/SJFPN);

    return 0;

}

4.5.4 SJF(最短进程优先调度)算法模块

int SJF(){              //短作业优先算法

    int temp_time=0;    //当期那时间

    int i=0,j;

    int PID_ORDERED,PRESENT_PNUMBER;      //进程编号,当前已执行进程个数

    float run_time;

    run_time=Process[i].SJF_ALLTIME;

    j=1;

    while((j<SJFPN)&&(Process[i].ArrivalTime==Process[j].ArrivalTime))    //判断是否有两个进程同时到达

    {

        if(Process[j].SJF_ALLTIME<Process[i].SJF_ALLTIME)

        {

            run_time=Process[i].SJF_ALLTIME;

            i=j;

        }

        j++;

    }

    //查找下一个被调度的进程

    //对找到的下一个被调度的进程求相应的参数

    PID_ORDERED=i;

    Process[PID_ORDERED].ServiceTime=Process[PID_ORDERED].ArrivalTime;

    Process[PID_ORDERED].FinishTime=Process[PID_ORDERED].ServiceTime+Process[PID_ORDERED].SJF_ALLTIME;

    Process[PID_ORDERED].STATE=1;

    temp_time=Process[PID_ORDERED].FinishTime;

    Process[PID_ORDERED].order=1;

    PRESENT_PNUMBER=1;

    while(PRESENT_PNUMBER<SJFPN)

    {

        for(j=0;j<SJFPN;j++)

        {

            if((Process[j].ArrivalTime<=temp_time)&&(!Process[j].STATE))

            {

                run_time=Process[j].SJF_ALLTIME;

                PID_ORDERED=j;

                break;

            }

        }

        for(j=0;j<SJFPN;j++)

        {

            if((Process[j].ArrivalTime<=temp_time)&&(!Process[j].STATE))

                if(Process[j].SJF_ALLTIME<run_time)

                {

                    run_time=Process[j].SJF_ALLTIME;

                    PID_ORDERED=j;

                }

        }

        //查找下一个被调度的进程

        //对找到的下一个被调度的进程求相应的参数

        Process[PID_ORDERED].ServiceTime=temp_time;

        Process[PID_ORDERED].FinishTime=Process[PID_ORDERED].ServiceTime+Process[PID_ORDERED].SJF_ALLTIME;

        Process[PID_ORDERED].STATE=1;

        temp_time=Process[PID_ORDERED].FinishTime;

        PRESENT_PNUMBER++;

        Process[PID_ORDERED].order=PRESENT_PNUMBER;

    }return 0;

}

5 系统测试 (UTF-8编码  可在 WINDOWS &LINUX环境下运行)

5.1Linux环境下编译主程序生成a.out文件

操作系统课程设计进程调度模拟

5.2运行a.out文件  (运行时可选择PRIORITY以及ALLTIME的生成方式)

操作系统课程设计进程调度模拟

5.2.1轮转调度算法的实现演示

操作系统课程设计进程调度模拟

5.2.2静态优先级调度算法的实现演示

操作系统课程设计进程调度模拟

5.2.3动态优先级调度算法的实现演示

操作系统课程设计进程调度模拟

5.2.4最短进程优先调度算法的实现演示  (为体现各进程的作业时长选择手动输入)

操作系统课程设计进程调度模拟

6 设计小结

本次模拟,实现了进程的轮转调度、静态优先级调度、动态优先级调度、最短进程优先调度。在整个实现过程中,出现了许多问题,最值得注意的问题如下,:

  1. 代码编写过程中的问题
    1. 四种调度算法中,动态优先级调度算法较为复杂,在实现进程的优先级更新时出现了较大的困难
    2. 在对静态优先级进行模拟时,由于对ALLTIME的使用限制,造成对ALLTIME的更新操作正常,最终通过添加num计数器,解决了ALLTIME在进程执行结束后归零的问题
    3. 由于各种调度方法的要求不一,因此对PCB结构的定义也出现了一定的选择问题
  1. 代码合并中的问题
    1. 对每种调度算法采用了不同的PCB结构,因此各PCB中的属性不一
    2. 每种调度算法中对某些属性的命名产生了冲突
    3. 在对程序进行合并时,最初使用了GOTO语句,但在考虑后,将程序更改为了SWITCH分支结构
  2. 程序运行中的问题
    1. 使用了部分Linux操作系统不支持的库函数,在Linux环境下运行时出现了部分编译错误。如gets()函数的使用,最终将其更改为了cin.get()函数。
    2. 在对库函数做修改后,Linux环境下运行程序时,四种调度均可正常实现,但对SP算法的调试并未彻底完成。当在Windows环境下使用原库函数时,程序可以正常无误地运行;在虚拟机中运行时,目前还未完成:由于库函数的使用导致“未知原因造成SP算法中,对4个及以上进程调度出现无限循环”的BUG。

本次模拟,到此并没有真正结束,对于程序的调试并没有真正达到我们满意的效果,但在Windows系统上已然完善,后续会继续对Linux操作系统下因为库函数的问题导致的程序细微异常进行处理,直至完善。文章来源地址https://www.toymoban.com/news/detail-480923.html

到了这里,关于操作系统课程设计进程调度模拟的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 操作系统进程调度算法的模拟实现(c语言版本)

            前言: 本文旨在分享如何使用c语言对操作系统中的部分进程调度算法进行模拟实现,以及算法描述的讲解, 完整代码放在文章末尾,欢迎大家自行拷贝调用 目录 常见的调度算法 数据结构 先来先服务调度算法 算法模拟思路: 算法模拟:  最短作业优先调度算法

    2024年02月06日
    浏览(55)
  • 实现时间片轮转算法(模拟)计算机操作系统实验5:进程调度算法模拟-RR

    实验内容: 实现时间片轮转算法(模拟),要求如下: 1、用到的数据结构 /* PCB / struct PCB { pid_t pid;//进程 PID int state; //状态信息,1 表示正在运行,0 表示暂停,-1 表示结束 unsigned long runned_time;//已运行时间 unsigned long need_running_time;//剩余运行时间 }; / PCB集合 */ struct PCB pcb[TOT

    2024年02月04日
    浏览(55)
  • 操作系统课程设计-Linux 进程控制

    目录 前言 1 实验题目 2 实验目的 3 实验内容 3.1 进程的创建 3.1.1 步骤 3.1.2 关键代码 3.2 子进程执行新任务 3.2.1 步骤 3.2.2 关键代码 4 实验结果与分析 4.1 进程的创建 4.2 子进程执行新任务 5 代码 5.1 进程的创建 5.2 子进程执行新任务          本实验为课设内容,博客内容为

    2024年01月18日
    浏览(51)
  • 操作系统课程设计----模拟文件管理系统(c语言)

    1.采用高级语言编写程序模拟文件系统,文件系统采用多级目录结构,实现对文件和目录的创建、删除、重命名、变更权限、显示文件内容、修改文件内容等操作。 2.撰写课程设计报告。 编写程序模拟一个简单的文件系统,具体实验内容如下: (1)实现多级目录结构,而

    2024年01月21日
    浏览(50)
  • 页面置换算法模拟实现-操作系统课程设计基于Java

    存储管理的主要功能之一是合理的分配空间,请求页式存储管理是一种常用的虚拟存储管理技术。在地址映射过程中,若在页表中发现所要访问的页面不在内存,则产生中断,当发生中断时,系统必须在内存选择一个页面移出内存,调用页面置换算法,以便为调入新的页面让

    2024年02月07日
    浏览(43)
  • 操作系统(一):进程状态与进程调度

            操作系统作为计算机基础的四大件,系统学习无疑是十分重要的。在这个系列的文章中,荔枝会结合操作系统的知识进行归纳梳理,总结输出博文!下面这篇文章主要介绍的是进程状态和调度,重点是几种调度算法的理解和掌握,希望对正在学习的小伙伴有帮助

    2024年02月05日
    浏览(50)
  • 操作系统与进程调度

    操作系统是一组做计算机资源管理的软件的统称,我们在日常生活常接触到的操作系统有: windows、IOS、Android、鸿蒙,以及Linux系统 等等,那么 操作系统是什么?计算机是如何运行的? 计算机是由软件、硬件相互配合工作;事实上,操作系统可以看做是介于软硬件之间的一组软

    2024年02月05日
    浏览(68)
  • 【操作系统】进程调度

    目录 调度的概念 调度目标     所有系统     批处理系统     交互式系统     实时系统 调度算法     非抢占式调度算法         先来先服务         最短作业优先         非抢占式优先级调度     抢占式调度算法         最短剩余时间优先         轮转

    2024年02月04日
    浏览(42)
  • 操作系统实验(进程调度)

      1.1理解有关进程控制块、进程队列的概念。   1.2掌握进程优先权调度算法和时间片轮转调度算法的处理逻辑。   2.1设计进程控制块PCB的结构,分别适用于优先权调度算法和时间片轮转调度算法。   2.2建立进程就绪队列。   2.3编制两种进程调度算法:优先权调度

    2024年02月06日
    浏览(46)
  • 【操作系统核心概念】进程管理和进程调度

    本文主要讲的是操作系统的一些核心概念, 主要讲解 进程管理和进程调度 的问题, 当然学习完本篇并不会让你能从零打造一个操作系统, 而只是让读者有了对操作系统核心概念的基本认识. 关注收藏, 开始学习吧🧐 操作系统是一组做计算机资源管理的软件的统称 , 其本质上也

    2024年02月12日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包