模拟实现操作系统调度算法

来源:互联网 发布:海星计划软件 编辑:程序博客网 时间:2024/05/17 17:45

  之前学习操作系统的时候对操作系统的一些调度算法比较感兴趣,所以自己模拟实现了一下操作系统算法的调度,我主要模拟实现了短作业优先和先来先服务调度算法。代码有点长,加上测试代码估计有300行左右吧,放在这里的话看起来也不方便(算了,还是放在下面吧,免得看的人觉得麻烦)。我先把实现的结果截图放在下面吧,然后再附上代码,其实在我的github上面也有这些代码的,地址: https://github.com/admin-zou/DS/tree/master/scheduling





头文件: //scheduling.h

#ifndef _SCHEDULING_#define _SCHEDULING_#include <iostream>#include <stdlib.h>using namespace std;enum Tag{UNSHD,SHD}; //标记是否被调度过struct PCB{int      pcbid;//进程号size_t  arrtime;//到达时间size_t  sertime;//服务时间size_t  begtime;//开始时间size_t  endtime;//完成时间size_t  turntime;//周转时间float    weighttime;//带权周转时间PCB *   next;//指向下个节点的指针Tag     tag;//标记是否被调度过PCB(int n=0,size_t a=0,size_t s=0):pcbid(n),arrtime(a),sertime(s),begtime(0),endtime(0),turntime(0),weighttime(0),next(NULL),tag(UNSHD){}};class scheduling{public:scheduling():_curtime(0),_tasknum(0){_head = new PCB();}/////先来先服务算法void FIFS(){if(empty()){cout<<"没有任务";exit(-1);}_clear();  //清理一下,可重复计算_sort_t(); //按到达时间排序PCB* cur = _head->next;while(NULL != cur){if(_curtime < cur->arrtime){ _curtime = cur->arrtime; }cur->begtime = _curtime; cur->endtime = _curtime + cur->sertime;//完成时间等于开始时间加服务时间cur->turntime = cur->endtime - cur->arrtime; //周转时间=完成时间-到达时间cur->weighttime  = (float)cur->turntime / (float)cur->sertime;  //带权周转时间=周转时间/服务时间cur->tag = SHD; //标记为已经服务_curtime += cur->sertime;cur = cur->next;}}/////短作业void Short(){if (empty()){cout << "没有任务";exit(-1);}_clear();  //清理一下,可重复计算_sort_t(); //按到达时间排序PCB* cur = _head->next;while (NULL != cur){if (_curtime < cur->arrtime){_curtime = cur->arrtime;}cur->begtime = _curtime;cur->endtime = _curtime + cur->sertime;//完成时间等于开始时间加服务时间cur->turntime = cur->endtime - cur->arrtime; //周转时间=完成时间-到达时间cur->weighttime = (float)cur->turntime / (float)cur->sertime; //带权周转时间=周转时间/服务时间cur->tag = SHD; //标记为已经服务_curtime += cur->sertime;cur = cur->next;//将该进程调度完的时刻已经到达的进程按短作业优先排序_sort_l(cur,_curtime);  //从该进程开始进行短作业排序}}void Init_task(){int tasknum=0;size_t id=0;size_t atime=0;size_t stime=0;cout<<"请输入任务的个数:";cin>>tasknum;for(int i = 0; i<tasknum;i++){cout<<"请分别输入任务的编号,到达时间,运行时间:";cin>>id>>atime>>stime;push(id,atime,stime);}}void Push(){size_t id=0;size_t atime=0;size_t stime=0;cout<<"请分别输入任务的编号,到达时间,运行时间:";cin>>id>>atime>>stime;push(id,atime,stime);}void Print(){if(empty())return ;PCB* cur = _head->next;printf("进程号 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间 \n");while(NULL != cur){printf("%4d %6d %8d %9d %7d  %8d\t %0.2f\n",cur->pcbid, cur->arrtime ,cur->sertime ,cur->begtime, cur->endtime ,cur->turntime ,cur->weighttime);cur = cur->next;}}protected:bool empty(){return _tasknum == 0;}bool push(int n,size_t a,size_t s) //插入到链表尾部{PCB * newtask = new PCB(n,a,s);PCB * cur = _head;while(NULL != cur->next)cur =cur->next;cur->next=newtask;_tasknum++;return true;}void _clear(){if(empty())return ;PCB* cur = _head->next;while(NULL != cur){cur->begtime = 0;cur->endtime = 0;cur->turntime = 0;cur->weighttime = 0;cur->tag = UNSHD;cur = cur->next ;}_curtime = 0;}// 按照到达时间排序void _sort_t() {if(empty() || _tasknum == 1)return;PCB* prev = _head->next;PCB* cur = prev->next;for(int i = 0; i< _tasknum-1; i++){for(int j = 0; j<_tasknum-i-1; j++){if (prev->arrtime > cur->arrtime){_Swap(prev, cur);}prev = cur;cur = cur->next;}prev=_head->next;cur = prev->next;}}// 按照作业长短排序void _sort_l(PCB*& head,size_t curtime){if (NULL == head || NULL == head->next)return;PCB* prev = head;PCB* cur = prev->next;int size = 0;  //计算进程的数目PCB* tmp = head;while (tmp){++size;tmp = tmp->next;}for (int i = 0; cur->arrtime < curtime && i < size - 1; i++){if (prev->arrtime > curtime){//作业还没到达就不排序return;}for (int j = 0; j < size - i - 1; j++){if (cur && cur->arrtime <= curtime){int ptime = prev->sertime;int ctime = cur->sertime;if (ptime > ctime){_Swap(prev, cur);}}prev = cur;cur = cur->next;}prev = head;cur = prev->next;}}void _Swap(PCB * prev,PCB * cur){swap(prev->arrtime,cur->arrtime);swap(prev->pcbid ,cur->pcbid );swap(prev->sertime ,cur->sertime );}private:PCB *_head;size_t  _curtime;size_t  _tasknum;//作业个数};#endif

测试文件:

#define_CRT_NOWANRINGS#include"scheduling.h"int main(){int select=1;scheduling mytask;while(select){cout<<"****************************"<<endl;cout<<"*   1.初始化               *"<<endl;cout<<"*   2.新插入一个进程       *"<<endl;cout<<"*   3.先来先服务调度算法   *"<<endl;cout<<"*   4.短作业调度算法       *"<<endl;cout<<"*   5.显示调度情况         *"<<endl;cout<<"*   0.退出                 *"<<endl;cout<<"****************************"<<endl;int item=0;cout<<"请输入:";cin>>select;switch(select){case 1:mytask.Init_task();break;case 2:mytask.Push();break;case 3:mytask.FIFS();break;        case 4:mytask.Short();break;case 5:mytask.Print();cout << endl;break;default:break;}}return 0;}//测试条件/*51 0 42 2 43 3 34 5 65 6 3*/

   总结:

       1.上面的程序基于是我对操作系统调度算法的理解所写出来的,主要模拟了先来先服务和短作业优先调度两种调度算法,其中涉及到了c++,数据结构以及操作系统和算法等方面的只是,实现它确实大有所益。

       2.在上面的小项目中我是通过计算出各种调度算法的周转时间,带权周转时间等等来评价调度算法的效率的,能够在一定范围内评估调度算法的性能,以及某些场景适合于使用哪种调度算法。

      3.我是通过单链表来组织相关的作业的调度需要的数据的,这样确实有好处,也有缺陷,这和链表的优缺点相对应。不过在数据量较小的时候还是很不错的。

    其中主要的难点在于很难分析出所有可能出现的情况,以及各种情况下的行为。还有就是,需要对操作系统的调度算法有一定的理解,否则就容易出现于实际不符的结果,比如说短作业优先调度,怎样理解这种调度方式呢,我举个例子吧:一开始时只有一个作业在调度,但是其所需时间比较长,在他执行过程中来了其他作业,但是作业时间很短,先调度这个短作业可能会更优,那么我们需要怎么处理呢,这就涉及到了是否允许抢占资源的问题(当然在我的实现中是不可抢占资源的)。最后说明一下在开发的时候一定要多调试,减少bug,增加程序的健壮性。



0 0
原创粉丝点击