模拟进程调度

来源:互联网 发布:2016年淘宝卖什么最好 编辑:程序博客网 时间:2024/05/30 07:12

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

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

进程名时间花销优先度P1103P211P323P414P552

多级反馈队列中,第一级的时间片是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 5struct 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 Outvoid 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;}


原创粉丝点击