四种进程调度方法

#include <iostream>
#include <windows.h>
#include <queue>
#include <list>
using namespace std;
int initial_id=0;//全局变量,用于初始化新队列的id值
struct PCB//结构体,包含了一个进程状态的所有信息
{
    int id;//进程表指数
    int needtime;//进程剩余需要占用CPU时间
    int runtime;//进程运行完毕需要占用CPU的时间
    int starttime=0;//进程就绪时间
    int whetherblock;//设定该进程是否会出现阻塞
    int startblock=0;//进程开始运行startblock个时间片后开始阻塞
    int blocktime=0;//进程被阻塞的时间
    int state;//运行 1,就绪 0,阻塞 -1,三种状态
};
class ProcessScheduler//调度进程的类
{
public:
    void CreateProcedureQueue(int flag);
    void CreateProcedureList(int flag);
    void FCFS();
    void SJF();
    void SRT();
    void RR();
    void Display();
private:
    queue<PCB> Queue;
    list<PCB> List;
    int capacity;
};

void ProcessScheduler::CreateProcedureQueue(int flag)//用来创建新的进程(队列)
{
    PCB item;
    item.id=++initial_id;
    item.needtime=rand()%19+1;//取随机数,用来初始化needtime,让每次测试结果都不同
    item.runtime=item.needtime;
    item.state=0;
    item.whetherblock=rand()%2;
    if(item.whetherblock==1)
    {
        item.startblock=rand()%(item.needtime);//这样可以保证阻塞的相对开始时间一定小于进程的运行时间。
        item.blocktime=1;
    }
    else
        item.startblock=item.runtime;
    Queue.push(item);
    cout<<"新进程号:"<<item.id<<" 执行所需时间"<<item.needtime;
    if(flag==1)
    {if(item.whetherblock==1)//1代表考虑阻塞
        {
         cout<<" 有阻塞";
         cout<<" 阻塞发生时,进程已运行的时间"<<item.startblock<<'\n';
        }
        else
            cout<<" 无阻塞"<<'\n';
    }
    else
        cout<<'\n';
}
void ProcessScheduler::CreateProcedureList(int flag)//用来创建新的进程(列表)方法类似列表
{
    PCB item;
    item.id=++initial_id;
    item.needtime=rand()%19+1;
    item.runtime=item.needtime;
    item.state=0;
    item.whetherblock=rand()%2;
    if(item.whetherblock==1)
    {
        item.startblock=rand()%(item.needtime);
        item.blocktime=1;
    }
    else
        item.startblock=item.runtime;
    List.push_back(item);
    cout<<"新进程号:"<<item.id<<" 执行所需时间"<<item.needtime;
    if(flag==1)
    {
        if(item.whetherblock==1)
        {
        cout<<" 有阻塞";
        cout<<" 阻塞发生时,进程已运行的时间"<<item.startblock<<'\n';
        }
        else
            cout<<" 无阻塞"<<'\n';
    }
    else
        cout<<'\n';
}
/*

FCFS算法,先来先服务,建立队列,按队列顺序执行即可。
如果发生了阻塞,把阻塞中的队首扔到队列后面。

*/
void ProcessScheduler::FCFS()
{
    int i=0;
    int stime=0;
    int flag=0;
    int count=0;
    cout<<"******************************"<<'\n';
    cout<<"FCFS算法演示(先来先服务算法)"<<'\n';
    cout<<"建立5个进程"<<'\n';
    cout<<"默认这5个进程都已经就绪"<<'\n';
    for(i=0;i<5;i++)
            CreateProcedureQueue(1);
        while(!Queue.empty())
        {
            PCB *p=&Queue.front();
            while(p->needtime>(p->runtime-p->startblock))
                {
                    //Sleep(1000);
                        stime++;
                        cout<<"时间片"<<stime;
                        cout<<""<<p->id<<"号进程运行 "<<'\n';
                        p->needtime--;
                }
            if(p->needtime==(p->runtime-p->startblock))
                {
                    //Sleep(1000);
                    if((p->runtime-p->startblock)==0)
                        Queue.pop();
                    else
                    {
                        cout<<"进程"<<p->id<<"发生阻塞,默认需要1个时间片进入就绪状态."<<'\n';
                        p->needtime--;
                        Queue.push(Queue.front());
                        Queue.pop();
                    }

                }
            else if(p->needtime<(p->runtime-p->startblock))
            {
                if((p->runtime-p->startblock)>0)
                    p->needtime++;
               // Sleep(1000);
                while(p->needtime>0)
                {
                    //Sleep(1000);
                     stime++;
                     cout<<"时间片"<<stime;
                     cout<<""<<p->id<<"号进程运行 "<<'\n';
                     p->needtime--;
                }
                Queue.pop();
            }
        }
        initial_id=0;
        cout<<"演示完毕"<<'\n';
        cout<<"******************************"<<'\n';
        Display();
}
/*
   SJF短作业优先,建立链表每次选择needtime最短的运行。

*/
void ProcessScheduler::SJF()
{
    int i=0;
    int stime=0;
    cout<<"******************************"<<'\n';
    cout<<"SJF算法演示(短作业优先算法)"<<'\n';
    cout<<"建立5个进程"<<'\n';
    cout<<"不考虑阻塞问题了,因为和上面差不多,偷懒了..."<<'\n';
    for(i=0;i<5;i++)
        CreateProcedureList(0);
        while(!List.empty())
        {
            std::list<PCB>::iterator p=List.begin();
            std::list<PCB>::iterator min=List.begin();
            for(;p!=List.end();++p)
            {
                if(p->needtime<min->needtime)
                    {
                        min=p;
                    }
            }
            while(min->needtime!=0)
            {
                stime++;
                cout<<"时间片"<<stime;
                cout<<""<<min->id<<"号进程运行 "<<'\n';
                min->needtime--;
            }
            List.erase(min);
        }
        initial_id=0;
        cout<<"演示完毕"<<'\n';
        cout<<"******************************"<<'\n';
        Display();
}
/*
最短剩余算法,每当有新的进程就绪,就重新挑出当前最短剩余时间的进程。

因为不是顺序的方式,所以要用链表

默认的2个时间片插入一个进程,这些默认值都可以修改

*/
void ProcessScheduler::SRT()
{
    int i=0;
    int stime=0;
    int a=5;//进程的数量
    int s=2;//为了方便计算。自己默认的每隔s时间插入一个进程
    cout<<"******************************"<<'\n';
    cout<<"SRT算法演示(最短剩余时间算法)"<<'\n';
    cout<<"每隔"<<s<<"个时间片插入一个新进程"<<'\n';
    cout<<"一共插入了"<<a<<""<<'\n';
        CreateProcedureList(0);
        a--;
        while(!List.empty())
        {
              std::list<PCB>::iterator p=List.begin();
              std::list<PCB>::iterator min=List.begin();
              if(stime==0)
              for(i=0;i<s;i++)
              {
                  stime++;
                  cout<<"时间片"<<stime;
                  cout<<""<<p->id<<"号进程运行 "<<'\n';
                  p->needtime--;
                  if(p->needtime==0)
                            List.erase(min);

              }
              if(stime%s==0)
              {
                  if(a>0)
                  CreateProcedureList(0);
                  a--;
                  for(;p!=List.end();++p)
                    {
                        if(p->needtime<min->needtime)
                        {
                            min=p;
                        }
                    }
                    for(int j=0;j<s;j++)
                    {
                        stime++;
                        cout<<"时间片"<<stime;
                        cout<<""<<min->id<<"号进程运行 "<<'\n';
                        min->needtime--;
                        if(min->needtime==0)
                            {
                                List.erase(min);
                                break;
                            }
                    }
              }
              else if(stime%s!=0)
              {

                  stime++;
                  cout<<"时间片"<<stime;
                  cout<<""<<p->id<<"号进程运行 "<<'\n';
                  p->needtime--;
                  if(min->needtime==0)
                    List.erase(min);
              }
              else
                break;
        }
        initial_id=0;
        cout<<"演示完毕"<<'\n';
        cout<<"******************************"<<'\n';
        Display();
}
/*

RR轮转法,每隔一定时间片进行下一个进程的分配

用队列排列这些进程,设定一个计时器,每隔n次就将队列头插到尾上


*/
void ProcessScheduler::RR()
{
    int i=0;
    int stime=0;
    int temp=0;
    int count;//计数器,表示每隔5个时间片中断一次
    cout<<"******************************"<<'\n';
    cout<<"RR算法演示(轮转算法)"<<'\n';
    cout<<"建立5个进程"<<'\n';
    cout<<"默认每隔5个时间片进行一次轮转"<<'\n';
    for(i=0;i<5;i++)
        CreateProcedureQueue(0);
         while(!Queue.empty())
        {
            PCB *p=&Queue.front();
            for(count=5;count>0;count--)
            {
                if(p->needtime!=0&&count>1)
                    {

                        stime++;
                        cout<<"时间片"<<stime;
                        cout<<""<<p->id<<"号进程运行 "<<'\n';
                        p->needtime--;
                    }
                    else if(p->needtime!=0&&count==1)
                    {

                        stime++;
                        cout<<"时间片"<<stime;
                        cout<<""<<p->id<<"号进程运行 "<<'\n';
                        p->needtime--;
                        Queue.push(Queue.front());
                        Queue.pop();
                    }
                    else if(p->needtime==0&&!Queue.empty())
                    {

                        Queue.pop();
                        if(!Queue.empty())
                        p=&Queue.front();
                        if(p->needtime!=0)
                        {
                            stime++;
                            cout<<"时间片"<<stime;
                            cout<<""<<p->id<<"号进程运行 "<<'\n';
                            p->needtime--;
                        }
                    }

            }

        }
        initial_id=0;
        cout<<"演示完毕"<<'\n';
        cout<<"******************************"<<'\n';
        Display();
}
void ProcessScheduler::Display()
{
    int key;
    cout<<"请输入数字选择演示哪个算法"<<'\n';
    cout<<"1:FCFS算法"<<'\n';
    cout<<"2: SJF算法"<<'\n';
    cout<<"3: SRT算法"<<'\n';
    cout<<"4: RR算法"<<'\n';
    cout<<"其他任意键: 结束"<<'\n';
    cin>>key;
    switch(key)
    {
    case 1:
        FCFS();
        break;
    case 2:
        SJF();
        break;
    case 3:
        SRT();
        break;
    case 4:
        RR();
        break;
    default:
        break;
    }
}

int main()
{

        ProcessScheduler test;
        test.Display();
        return 0;
}

 

posted @ 2016-04-12 21:38  HyouGenn  阅读(2201)  评论(0编辑  收藏  举报