操作系统进程调度模拟程序

来源:互联网 发布:免费抢票软件 编辑:程序博客网 时间:2024/05/17 18:28

//time.h

#ifndef TIME_H
#define TIME_H

/*一个模拟时间的类,被PCB和Pattemper使用
 *作为数据成员,或者作为参数进行传递,类
 *只定义了几个操作符重载的函数用来作为参数
 *和成员在计算中的使用。类本身会保证构造的时间
 *都是正确的格式,如果不争取会置为零值或者抛出异常
 *默认的复制控制符合要求
 */

#include <iostream>
#include <exception>
using namespace std;

//当时间不正确的时候抛出这也异常
class WrongTime: public exception
{
 public:
  virtual const char* what() const
  {
   return "时间是错误的!";
  }
};

class Time
{
 public:
  explicit Time(int hour = 0, int minute = 0, int second = 0);
           Time& operator +=(const Time &t)throw(WrongTime);
     Time& operator -=(const Time &t)throw(WrongTime);
     friend ostream& operator<<(ostream &os, const Time &t)
     {
      os<<t.m_hour<<"-"<<t.m_minute<<"-"
       <<t.m_second<<endl;
      return os;
     }
     friend bool operator <=(const Time &lt, const Time &rt)
     {
      int ltime, rtime;
      ltime = lt;
      rtime = rt;
      if (ltime <= rtime)
       return true;
      else
       return false;
     }
     //隐式转换操作符,将时间格式转换为整数(秒)
     operator int ()const;
    
     bool operator ==(const Time &t);
 private:
  int m_hour;
  int m_minute;
  int m_second;
  //时间是否为正确的时间格式
  bool rightTime() const;
};

inline Time::operator int ()const
{
 return m_hour*3600+m_minute*60+m_second;
}

inline bool Time::operator == (const Time &t)
{
 return (m_hour == t.m_hour &&
      m_minute == t.m_minute &&
   m_second == t.m_second);
}
#endif

//timefun.cpp

#include "time.h"

Time::Time(int hour, int minute, int second):
     m_hour(hour), m_minute(minute), m_second(second)
     {
      //如果时间格式不正确,全部赋值0
    if (!rightTime())
    {
     m_hour = 0;
     m_minute = 0;
     m_second = 0;
    }
     }

Time& Time::operator +=(const Time &t) 
{
 if (rightTime() && t.rightTime())
 {
  m_hour += t.m_hour;
  m_minute += t.m_minute;
  m_second += t.m_second;

  if (m_second >= 60)
  {
   m_minute += m_second / 60;
   m_second %= 60;
  }

  if (m_minute >= 60)
  {
   m_hour += m_minute / 60;
   m_minute %= 60;
  }

  return *this;
 }

 throw WrongTime();
}

//当左操作数小于右操作数的时,不会得到负值,而是零值

Time& Time::operator -=(const Time &t)throw(WrongTime)
{
 if (*this <= t)
 {
  m_hour = 0;
  m_minute = 0;
  m_second = 0;
 }

 else
 {
  if (m_second < t.m_second)
  {
   if (m_minute)
   {
    --m_minute;
    m_second += 60;
   }

   else
   {
    --m_hour;
    m_minute += 59;
    m_second += 60;
   }
  }
  m_second -= t.m_second;

  if (m_minute < t.m_minute)
  {
   --m_hour;
   m_minute += 60;
  }

  m_minute -= t.m_minute;
  m_hour -= t.m_hour;
 }

 return *this;
}

bool Time::rightTime() const
{
 if ((m_hour < 0 || m_hour > 24) || (m_minute < 0 || m_minute > 60)
   || (m_second < 0 || m_second > 60))
   return false;

 return true;
}


//pcb.h

#ifndef PCB_H
#define PCB_H

/*模拟进程控制快,包括进程的名字,进程的优先级,
 *进程需要执行的时间,进程等待的时间等进程的信息。
 *同时类有几个友元函数作为在几个进程调度算法中作
 *为排序的准则进行调用。做为系统感知进程的唯一标识,
 *进程控制块从一开始就不能为空,所以不能有默认的
 *构造函数,默认的复制操作符合要求
 */

#include <iostream>
#include <string>
#include "time.h"
using namespace std;

//一些标识状态的常量
const int WAITE = 1;
const int RUN = 2;
const int FINISH = 3;

class PCB
{
 public:
  //不提供默认的构造函数
  PCB(const string &name, const Time &runtime, int level);

  //设置进程开始运行的时间
  void setBeginTime(const Time &t);

  //设置进程的等待时间
  void setWaiteTime(const Time &t);

  //按形参设置进程运行的时间
  void setRTime(const Time &t);

  //判断进程是否已经完成
  bool pcbFinish();

  //当才用先来先服务等算法的时候,系统一次性
  //提供给进程足够的运行时间,用这个函数
  void setRTime();

  //返回进程运行的时间
  Time& returnRTime();

  //返回进程的响应比
  double returnM_R();
  
  bool operator ==(const PCB &p);

  //用于先来先服务算法排序
 friend bool levelSortRule(const PCB &lp, const PCB &fp);
        //用于最短作业优先算法排序

 friend bool sjfSortRule(const PCB &lp, const PCB &rp);
        //用于最高响应比优先法排序

 friend bool hrnSortRule(const PCB &lp, const PCB &rp);

  //输出进程的信息
 friend ostream& operator <<(ostream &os, const PCB &p)
  {
   os<<"进程的名称: "<<p.m_name<<endl;
   os<<"进程的优先级: "<<p.m_level<<endl;
   os<<"进程需要运行的时间: "<<p.m_runTime;
   os<<"进程开始的时间: "<<p.m_beginTime;
   os<<"进程等待的时间: "<<p.m_waiteTime;
   os<<"进程结束的时间: "<<p.m_endTime;
   os<<"进程的响应比: "<<p.m_r<<endl;
   return os;
  }
 private:
  //进程的名字
  string m_name;
  //进程需要运行的时间
  Time   m_runTime;
  //进程的优先级
  int    m_level;
  //进程开始执行的时间
  Time   m_beginTime;
  //进程执行结束的时间
  Time   m_endTime;
  //进程等待的时间
  Time   m_waiteTime;
  //进程的状态
  int    m_state;
  //进程的响应比
  double m_r;
};

inline void PCB::setBeginTime(const Time &t)
{
 m_beginTime = t;
}

inline void PCB::setWaiteTime(const Time &t)
{
 m_waiteTime += t;
 int wt, rt;
 wt = m_waiteTime;
 rt = m_runTime;
 m_r = 1.0 + wt/rt;
}

inline bool PCB::pcbFinish()
{
 return m_state == FINISH;
}

inline void PCB::setRTime()
{
 m_endTime += m_runTime;
 m_runTime -= m_runTime;
 m_state = FINISH;
 --m_level;
}

inline Time& PCB::returnRTime()
{
 return m_runTime;
}

inline bool levelSortRule(const PCB &lp, const PCB &rp)
{
 return lp.m_level >= rp.m_level;
}

inline bool sjfSortRule(const PCB &lp, const PCB &rp)
{
 return lp.m_runTime <= rp.m_runTime;
}

inline bool hrnSortRule(const PCB &lp, const PCB &rp)
{
 return lp.m_r >= rp.m_r;
}

inline double PCB::returnM_R()
{
 return m_r;
}

#endif

//pcbfun.cpp

#include "pcb.h"

PCB::PCB(const string &name, const Time &runtime, int level):
         m_name(name), m_runTime(runtime), m_level(level)
   {
    m_state = WAITE;
    m_r = 0.0;
   }

void PCB::setRTime(const Time &t)
{
 if (m_runTime <= t)
 {
  m_runTime -= m_runTime;
  m_state = FINISH;
 }

 else
  m_runTime -=  t;

 m_endTime += t;
 --m_level;
}

bool PCB::operator ==(const PCB &p)
{
 return (m_name == p.m_name && m_runTime == p.m_runTime &&
      m_level == p.m_level);
}

//pattemper.h

#ifndef PATTEMPER_H
#define PATTEMPER_H

/*进程调度过程的模拟,算法包括:先来先服务,
 *最高优先级算法,最短作业优先算法,最高响应比算法。
 *进程开始执行的时间,进程平均等待的时间,时间片平均
 *长度在构造函数中都进行了设置。在最高优先级算法,最
 *高优先级算法和先来先服务算法中,进程的等待时间对算法
 *本身的影响很小,所以不予以考虑,也降低了复杂度。但在
 *最高响应比算法中需要用到。默认的复制控制符合要求
 */

#include <vector>
#include "pcb.h"
using namespace std;


class Pattemper
{
 public:
  Pattemper();
  //添加新的进程
  void add();

  //进程调度算法
  void operate();

 private:
  //先来先服务
  void fcfs();

  //最高优先级算法
  void level();

  //最短作业优先算法
  void sjf();

  //最高响应比优先算法
  void hrn();
  
 private:
  //设置的默认的开始时间
  Time  m_beginTime;
  //进程平均等待时间
  Time  m_eveWTime;
  //平均时间片长度
  Time  m_erTime;
  //保存进程信息
  vector<PCB> m_pvec;
};

#endif

//patfun.cpp

#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include "pattemper.h"
using namespace std;

//将默认的起始时间设置为零值,并从文件data.txt中读取进程

Pattemper::Pattemper():m_beginTime(Time()),m_eveWTime(Time(0,1,10)),
        m_erTime(0,10,10)
{
 ifstream infile("date.txt");
 string name;
 int hour, minute, second, level;

 while (infile>>name>>hour>>minute>>second>>level)
 {
  Time t(hour, minute, second);
  PCB p(name, t, level);
  m_pvec.push_back(p);
 }
}

//如果要添加的进程已经存在什么也不做

void Pattemper::add()
{
 cout<<"输入要添加的进程名: ";
 string name;
 cin>>name;
 cout<<endl;

 cout<<"进程需要运行的时间(格式: 小时  分钟 秒): ";
 int hour, minute, second;
 cin>>hour>>minute>>second;
 cout<<endl;

 cout<<"进程的优先级: ";
 int level;
 cin>>level;
 cout<<endl;

 Time t(hour, minute, second);
 PCB p(name, t, level);
 
 vector<PCB>::iterator ite;
 //这个函数学要容器元素自身拥有相等操作符重载
 ite = find(m_pvec.begin(), m_pvec.end(), p);
 if (ite == m_pvec.end())
  m_pvec.push_back(p);
}

//各种算法的调度

void Pattemper::operate()
{
 cout<<"进程调度的几种算法: "<<endl;
 cout<<"1   先来先服务      "<<endl;
 cout<<"2   优先级法        "<<endl;
 cout<<"3   最短作业优先    "<<endl;
 cout<<"4   最高响应比法    "<<endl;
 cout<<endl;

 cout<<"请选择算法: ";
 int choice;
 cin>>choice;
 cout<<endl;

 switch (choice)
 {
  case 1: fcfs();
    break;
  case 2: level();
    break;
  case 3: sjf();
    break;
  case 4: hrn();
       break;
 }
}

//先来先服务算法,按先后顺序提供给进程足够的运行时间共运行
//打印出进程运行前后的情况,为了减少复杂度,由于等待时间
//对本算法没没什么太大的影响所以不予以考虑

void Pattemper::fcfs()
{
 vector<PCB>::iterator ite;

 while (!m_pvec.empty())
 {
  ite = m_pvec.begin();
  cout<<"运行前进程的情况: "<<endl;
  cout<<*ite<<endl;
  ite->setBeginTime(m_beginTime);
  m_beginTime += ite->returnRTime();
  ite->setRTime();
  cout<<"运行后进程的情况: "<<endl;
  cout<<*ite<<endl;
  m_pvec.erase(ite);
 }
}

//最高优先级算法,进程每得到一次处理机将进程的优先级减一
//如果进程在系统给的时间内没有运行完,则将它排到对未
//否则删除。为了减少复杂度,由于等待时间对本算法的影响很小
//所以不予以考虑

void Pattemper::level()
{
 vector<PCB>::iterator ite;

 while (!m_pvec.empty())
 {
  sort(m_pvec.begin(), m_pvec.end(), levelSortRule);
  ite = m_pvec.begin();

  cout<<"运行前进程的情况: "<<endl;
  cout<<*ite<<endl;

  ite->setBeginTime(m_beginTime);
  ite->setRTime(m_erTime);

  cout<<"运行后进程的情况: "<<endl;
  cout<<*ite<<endl;

  if (ite->pcbFinish())
   m_pvec.erase(ite);

  m_beginTime += m_erTime;
 }
}

//最短作业优先算法,处理器提供给足够的时间运行,
//运行结束删除,打印出运行前后进程的信息,为了
//减少程序的复杂度,由于等待时间对本算法的影响很小
//所以不予以考虑

void Pattemper::sjf()
{
 vector<PCB>::iterator ite;

 while (!m_pvec.empty())
 {
  sort(m_pvec.begin(), m_pvec.end(), sjfSortRule);
  ite = m_pvec.begin();

  cout<<"运行前进程的情况: "<<endl;
  cout<<*ite<<endl;

  ite->setBeginTime(m_beginTime);
  m_beginTime += ite->returnRTime();
  ite->setRTime();

  cout<<"运行后进程的情况: "<<endl;
  cout<<*ite<<endl;

  m_pvec.erase(ite);
 }
}

//最高响应比优先算法,这个和进程的等待时间有关系,不仅要设置平均等待
//时间,每个进程运行结束还要将它的运行时间做为等待时间赋值给它后面的
//进程,打印进程运行前后的信息

void Pattemper::hrn()
{
 vector<PCB>::iterator ite;
 ite = m_pvec.begin();

 for (; ite != m_pvec.end(); ++ite)
  ite->setWaiteTime(m_eveWTime);

 sort(m_pvec.begin(), m_pvec.end(), hrnSortRule);

 while (!m_pvec.empty())
 {
  ite = m_pvec.begin();
  cout<<"运行前进程的情况: "<<endl;
  cout<<*ite<<endl;

  ite->setBeginTime(m_beginTime);
  m_beginTime += ite->returnRTime();

  vector<PCB>::iterator fite = ite + 1;
  for (; fite != m_pvec.end(); ++fite)
   fite->setWaiteTime(ite->returnRTime());

  ite->setRTime();
  cout<<"运行后进程的情况: "<<endl;
  cout<<*ite<<endl;

  m_pvec.erase(ite);
 }
}

//main.cpp

#include <iostream>
#include "pattemper.h"
using namespace std;

int main()
{
 cout<<"模拟进程调度的过程: "<<endl;
 cout<<"1    添加进程       "<<endl;
 cout<<"2    进程调度算法   "<<endl;

 int choice;
 Pattemper user;

 cout<<"选择: ";
 cin>>choice;
 cout<<endl;
 char flag('y');

 switch (choice)
 {
  case 1: while (flag == 'y' || flag == 'Y')
    {
     user.add();
     cout<<"y/n: ";
     cin>>flag;
     cout<<endl;
    }
    break;
  case 2: user.operate();
    break;
  default: cout<<"选择错误!"<<endl;
    break;
 }

 return 0;
}

 

原创粉丝点击