模拟进程调度

通过C++编程来模拟三种进程调度方式:FCFS(先来先服务),Priority Scheduling(优先度调度)和Multilever feedback queue (多级反馈队列)

现有5个进程同时一次进入进程调度器

进程名时间花销优先度
P1103
P211
P323
P414
P552

多级反馈队列中,第一级的时间片是1,第二级是2.....以此类推



模拟进程调度程序说明

 

两个结构

首先介绍两个数据结构

Process结构:

structProcess

{

    char name[NAME_LENGTH];//进程名字

    int priority;//优先度

    int cost;//进程执行需要时间开销

    int used;//已用时间

    int wait_time;//等待时间

    Process(char na[],int ct,int prio)

    {

        strcpy(name,na);

        cost = ct;

        priority = prio;

        wait_time = 0;

        used = 0;

    }

    void print()

    {

        printf("Process Name:%s \tPriorityValue:%d \tWaiting time:%d\n",name,priority,wait_time);

    }

};

这个结构用来保存进程信息。

然后通过创建一个Process指针数组来保存要处理的进程

    Process *process_list[PROCESS_NUM];

    process_list[0]=newProcess("P1",10,3);

    process_list[1]=newProcess("P2",1,1);

    process_list[2]=newProcess("P3",2,3);

    process_list[3]=newProcess("P4",1,4);

process_list[4]=new Process("P5",5,2);

MultiQueue结构:

struct MultiQueue

{

   queue<Process *> plist;//该级的队列

   int quantum_time;//该级别的时间片

   int lever;//记录级别

   MultiQueue *next;//下一级队列

   MultiQueue()

    {

       lever = 0;

       next = NULL;

       quantum_time = 0;

       while(!plist.empty())

           plist.pop();

    }

};

这个多级队列结构是服务于多级反馈队列进程调度服务的。

一个MultiQueue就是一个多级反馈队列。

quantum_time定义了该级别的时间片

plist则是保存了在这个级别队列里面的待运行进程

lever记录当前是第几个级别的

 

三个方法

由于要模拟先到先服务(FIFO/FCFS)、优先数调度(Priority Scheduling)和多级反馈队列调度(Multilevel feedback queue),所以我实现了三个方法分别表示这三种调度方法,每一个方法的参数都是待调度进程数组和数组规模。也就是上文利用Process创建的指针数组Process *process_list[PROCESS_NUM].

First Come,First Served方法

//First Come,First Served 先来先服务 ,即FIFO,First In,First Out

void FCFS(Process* plist[],int psize)

{

   printf("First Come First Served running...\n");

   queue< Process * > fcfs_list;

   while(!fcfs_list.empty())fcfs_list.pop();

   for (int i=0;i<psize;i++)

    {

       fcfs_list.push(plist[i]);

    }

   int time =0;

   while(!fcfs_list.empty())

    {

       Process * excu = fcfs_list.front();

       fcfs_list.pop();

       excu->wait_time = time;

       time += excu->cost;

       printf("%s excute %d timeunits...\n",excu->name,excu->cost);

    }

   printf("First Come First Served ending...\n");

   time = 0;

   for (int i=0;i<psize;i++)

    {

       plist[i]->print();

       time += plist[i]->wait_time;

    }

   double mwt = (double)time/psize;

   printf("Mean Waiting Time is %.2lf\n",mwt);

   printf("------------------------\n");

}

首先创建一个队列fcfs_list表示FCFS的待执行进程。然后按照plist[]的顺序把进程压进fcfs_list里面。接着就开始执行进程。

每次执行从fcfs_list取出最前面的进程,此时时间累加器time即为此进程的等待时间,并把该进程的执行时间累加紧time里面。一直执行直到fcfs_list为空。

这时每一个进程任务都已经执行完毕了,最后可以通过访问每一个进程的plist[i]->wait_time来得到平均等待时间并打印出来

Priority Scheduling方法

//Priority Scheduling优先数调度法,非抢占式

void PS(Process* plist[],int psize)

{

   printf("Priority Scheduling running...\n");

   //因为优先度调度需要根据优先度对进程进行排序后放进队列,为了不影响原顺序,用一个新的数组来暂存排序结果

   Process* sort_list[PROCESS_NUM];

   for (int i=0;i<psize;i++)

    {

       sort_list[i] = plist[i];

    }

   sort_priority(sort_list,psize);

   queue< Process * > ps_list;

   while(!ps_list.empty())

       ps_list.pop();

   for (int i=0;i<psize;i++)

    {

       ps_list.push(sort_list[i]);

    }

   int time =0;

   while(!ps_list.empty())

    {

       Process * excu = ps_list.front();

       ps_list.pop();

       excu->wait_time = time;

       time += excu->cost;

       printf("%s excute %d timeunits...\n",excu->name,excu->cost);

    }

   printf("Priority Scheduling ending...\n");

    time = 0;

   for (int i=0;i<psize;i++)

    {

       plist[i]->print();

       time += plist[i]->wait_time;

    }

   double mwt = (double)time/psize;

   printf("Mean Waiting Time is %.2lf\n",mwt);

   printf("------------------------\n");

}

由于优先数调度是根据每一个进程的优先数来判定进程的执行顺序,优先数越小,越早执行。

所以要先对进程进行一个优先数升序排序。为了不影响原进程数组的顺序。这里新建了一个plist[]的副本sort_list[],然后对sort_list[]进行升序排序,最后把sort_list[]排序后的结果按顺序压进优先数调度队列ps_list里面。

接着就开始执行进程。

每次执行从ps_list取出最前面的进程,此时时间累加器time即为此进程的等待时间,并把该进程的执行时间累加紧time里面。一直执行直到ps_list为空。

这时每一个进程任务都已经执行完毕了,最后可以通过访问每一个进程的plist[i]->wait_time来得到平均等待时间并打印出来

Multilevel feedback queue方法

//Multilevel feedback queue多级反馈队列调度

void MFQ(Process* plist[],int psize)

{

   printf("Multilevel feedback queue running...\n");

   MultiQueue *mq = new MultiQueue();

   MultiQueue *current;

   mq->quantum_time = 1;

   mq->lever = 1;

   for (int i=0;i<psize;i++)

    {

       plist[i]->used = 0;

       mq->plist.push(plist[i]);

    }

 

   int time = 0;

   current = mq;

   //只有没有下一级队列并且当前队列为空时,才退出

   while(! (current->plist.empty() && current->next==NULL))

    {

       if (current->plist.empty())

           current = current->next;

       else

       {

           Process * excu = current->plist.front();

           current->plist.pop();

           int todo_time = excu->cost - excu->used;

           if (todo_time > current->quantum_time )

           {

                todo_time =current->quantum_time;

                excu->used += todo_time;

                if (current->next==NULL)

                {

                    current->next = newMultiQueue();

                   current->next->quantum_time = current->quantum_time+1;

                    current->next->lever= current->lever+1;

                }

               current->next->plist.push(excu);

            }else

           {

                excu->wait_time = time -excu->used;

                excu->used += todo_time;

           }

           time += todo_time;

           printf("%s excute %d time units at %dlayer...\n",excu->name,todo_time,current->lever);

       }

    }

   printf("Multilevel feedback queue ending...\n");

   time = 0;

   for (int i=0;i<psize;i++)

    {

       plist[i]->print();

       time += plist[i]->wait_time;

    }

   double mwt = (double)time/psize;

   printf("Mean Waiting Time is %.2lf\n",mwt);

   printf("------------------------\n");

 

}

多级反馈队列把进程划分到多个级别里面执行,每一个级别的队列给与进程有限的运行时间,若所给时间内还没有执行完毕,则弹出此进程并把此进程放置到下一级进程里面继续执行。

而一般下一级队列要比上一级队列的能给与时间片要长。也就是说,如果第一级队列的时间片为1,时间片时间内不能完成,则弹到第二级队列执行,第二级的队列时间片可能就为2,以此类推。

在MFQ方法里面也是这么运作的。首先创建一个多级队列MultiQueue *mq = new MultiQueue(),用MultiQueue *current指示当前级别队列。一开始把所有进程压进mq->plist里面,也就是压进第一级的队列里面。然后开始执行进程

每执行一个进程,首先判断该进程还需要执行的时间能否在当前级别的时间片内完成,能完成则该进程的等待时间为excu-> wait_time = 当前时间time-该进程已用时间excu->used ;若是不能在该时间片内完成,则把此进程使用世家加上该级别的时间片世家todo_time = current->quantum_time;excu->used += todo_time;由于此进程仍需要执行,需要压进下一级的队列里面待执行,所以先检查下一级队列是否存在,不存在则创建下一级队列,然后压进下一级队列里面。

以上操作完成了就表示该进程在此级别里面的操作结束了。把该进程的使用时间todo_time 加到时间累加器time里面表示时间的使用time += todo_time;

一直重复这操作直到该级别的队列为空。若是下一级别队列不为空,则把当前队列指针移到下一级队列里面if (current->plist.empty())   current = current->next; 否则就表示所有进程都执行完毕了。

最后可以通过访问每一个进程的plist[i]->wait_time来得到平均等待时间并打印出来

附录

源代码

//Process Scheduling (Simulation)
/*
author:黎伟杰
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>

using namespace std;

#define NAME_LENGTH 255
#define PROCESS_NUM 5

struct Process
{
    char name[NAME_LENGTH];//进程名字
    int priority;//优先度
    int cost;//进程执行需要时间开销
    int used;//已用时间
    int wait_time;//等待时间
    Process()
    {
        wait_time = 0;
        used = 0;
    }
    Process(char na[],int ct,int prio)
    {
        strcpy(name,na);
        cost = ct;
        priority = prio;
        wait_time = 0;
        used = 0;
    }
    Process(Process &rhs)
    {
        strcpy(name,rhs.name);
        cost = rhs.cost;
        priority = rhs.priority;
        wait_time = rhs.wait_time;
        used = rhs.used;
    }
    void init(char na[],int ct,int prio)
    {
        strcpy(name,na);
        cost = ct;
        priority = prio;
        wait_time = 0;
        used = 0;
    }
    void print()
    {
        printf("Process Name:%s \tPriority Value:%d \tWaiting time:%d\n",name,priority,wait_time);
    }
};



void sort_priority(Process* plist[],int psize)
{
    int i = psize-1;
    Process *tmp;
    while(i>=0)
    {
        for (int j=0;j<i;j++)
        {
            if (plist[i]->priority<plist[j]->priority)
            {
                tmp = plist[i];
                plist[i] = plist[j];
                plist[j] = tmp;
            }
        }
        i--;
    }
}

//First Come,First Served 先来先服务 ,即FIFO,First In,First Out
void FCFS(Process* plist[],int psize)
{
    printf("First Come First Served running...\n");
    queue< Process * > fcfs_list;
    while(!fcfs_list.empty())fcfs_list.pop();
    for (int i=0;i<psize;i++)
    {
        fcfs_list.push(plist[i]);
    }
    int time =0;
    while(!fcfs_list.empty())
    {
        Process * excu = fcfs_list.front();
        fcfs_list.pop();
        excu->wait_time = time;
        time += excu->cost;
        printf("%s excute %d time units...\n",excu->name,excu->cost);
    }
    printf("First Come First Served ending...\n");
    time = 0;
    for (int i=0;i<psize;i++)
    {
        plist[i]->print();
        time += plist[i]->wait_time;
    }
    double mwt = (double)time/psize;
    printf("Mean Waiting Time is %.2lf\n",mwt);
    printf("------------------------\n");
}

//Priority Scheduling优先数调度法,非抢占式
void PS(Process* plist[],int psize)
{
    printf("Priority Scheduling running...\n");
    //因为优先度调度需要根据优先度对进程进行排序后放进队列,为了不影响原顺序,用一个新的数组来暂存排序结果
    Process* sort_list[PROCESS_NUM];
    for (int i=0;i<psize;i++)
    {
        sort_list[i] = plist[i];
    }
    sort_priority(sort_list,psize);
    queue< Process * > ps_list;
    while(!ps_list.empty())
        ps_list.pop();
    for (int i=0;i<psize;i++)
    {
        ps_list.push(sort_list[i]);
    }
    int time =0;
    while(!ps_list.empty())
    {
        Process * excu = ps_list.front();
        ps_list.pop();
        excu->wait_time = time;
        time += excu->cost;
        printf("%s excute %d time units...\n",excu->name,excu->cost);
    }
    printf("Priority Scheduling ending...\n");
    time = 0;
    for (int i=0;i<psize;i++)
    {
        plist[i]->print();
        time += plist[i]->wait_time;
    }
    double mwt = (double)time/psize;
    printf("Mean Waiting Time is %.2lf\n",mwt);
    printf("------------------------\n");
}

//多级队列,用链表实现
struct MultiQueue
{
    queue<Process *> plist;//该级的队列
    int quantum_time;//该级别的时间片
    int lever;//记录级别
    MultiQueue *next;//下一级队列
    MultiQueue()
    {
        lever = 0;
        next = NULL;
        quantum_time = 0;
        while(!plist.empty())
            plist.pop();
    }
};

//Multilevel feedback queue多级反馈队列调度
void MFQ(Process* plist[],int psize)
{
    printf("Multilevel feedback queue running...\n");
    MultiQueue *mq = new MultiQueue();
    MultiQueue *current;
    mq->quantum_time = 1;
    mq->lever = 1;
    for (int i=0;i<psize;i++)
    {
        plist[i]->used = 0;
        mq->plist.push(plist[i]);
    }

    int time = 0;
    current = mq;
    //只有没有下一级队列并且当前队列为空时,才退出
    while(! (current->plist.empty() && current->next==NULL))
    {
        if (current->plist.empty())
            current = current->next;
        else
        {
            Process * excu = current->plist.front();
            current->plist.pop();
            int todo_time = excu->cost - excu->used;
            if (todo_time > current->quantum_time )
            {
                todo_time = current->quantum_time;
                excu->used += todo_time;
                if (current->next==NULL)
                {
                    current->next = new MultiQueue();
                    current->next->quantum_time = current->quantum_time+1;
                    current->next->lever = current->lever+1;
                }
                current->next->plist.push(excu);
            }else
            {
                excu->wait_time = time - excu->used;
                excu->used += todo_time;
            }
            time += todo_time;
            printf("%s excute %d time units at %d layer...\n",excu->name,todo_time,current->lever);
        }
    }
    printf("Multilevel feedback queue ending...\n");
    time = 0;
    for (int i=0;i<psize;i++)
    {
        plist[i]->print();
        time += plist[i]->wait_time;
    }
    double mwt = (double)time/psize;
    printf("Mean Waiting Time is %.2lf\n",mwt);
    printf("------------------------\n");

}

int main()
{
    Process *process_list[PROCESS_NUM];
    process_list[0]=new Process("P1",10,3);
    process_list[1]=new Process("P2",1,1);
    process_list[2]=new Process("P3",2,3);
    process_list[3]=new Process("P4",1,4);
    process_list[4]=new Process("P5",5,2);
    FCFS(process_list,5);
    PS(process_list,5);
    MFQ(process_list,5);
    return 0;
}


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值