模拟实现操作系统调度算法
2016-04-06 22:01
597 查看
之前学习操作系统的时候对操作系统的一些调度算法比较感兴趣,所以自己模拟实现了一下操作系统算法的调度,我主要模拟实现了短作业优先和先来先服务调度算法。代码有点长,加上测试代码估计有300行左右吧,放在这里的话看起来也不方便(算了,还是放在下面吧,免得看的人觉得麻烦)。我先把实现的结果截图放在下面吧,然后再附上代码,其实在我的github上面也有这些代码的,地址: https://github.com/admin-zou/DS/tree/master/scheduling
头文件: //scheduling.h
测试文件:
总结:
1.上面的程序基于是我对操作系统调度算法的理解所写出来的,主要模拟了先来先服务和短作业优先调度两种调度算法,其中涉及到了c++,数据结构以及操作系统和算法等方面的只是,实现它确实大有所益。
2.在上面的小项目中我是通过计算出各种调度算法的周转时间,带权周转时间等等来评价调度算法的效率的,能够在一定范围内评估调度算法的性能,以及某些场景适合于使用哪种调度算法。
3.我是通过单链表来组织相关的作业的调度需要的数据的,这样确实有好处,也有缺陷,这和链表的优缺点相对应。不过在数据量较小的时候还是很不错的。
其中主要的难点在于很难分析出所有可能出现的情况,以及各种情况下的行为。还有就是,需要对操作系统的调度算法有一定的理解,否则就容易出现于实际不符的结果,比如说短作业优先调度,怎样理解这种调度方式呢,我举个例子吧:一开始时只有一个作业在调度,但是其所需时间比较长,在他执行过程中来了其他作业,但是作业时间很短,先调度这个短作业可能会更优,那么我们需要怎么处理呢,这就涉及到了是否允许抢占资源的问题(当然在我的实现中是不可抢占资源的)。最后说明一下在开发的时候一定要多调试,减少bug,增加程序的健壮性。
头文件: //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; } //测试条件 /* 5 1 0 4 2 2 4 3 3 3 4 5 6 5 6 3 */
总结:
1.上面的程序基于是我对操作系统调度算法的理解所写出来的,主要模拟了先来先服务和短作业优先调度两种调度算法,其中涉及到了c++,数据结构以及操作系统和算法等方面的只是,实现它确实大有所益。
2.在上面的小项目中我是通过计算出各种调度算法的周转时间,带权周转时间等等来评价调度算法的效率的,能够在一定范围内评估调度算法的性能,以及某些场景适合于使用哪种调度算法。
3.我是通过单链表来组织相关的作业的调度需要的数据的,这样确实有好处,也有缺陷,这和链表的优缺点相对应。不过在数据量较小的时候还是很不错的。
其中主要的难点在于很难分析出所有可能出现的情况,以及各种情况下的行为。还有就是,需要对操作系统的调度算法有一定的理解,否则就容易出现于实际不符的结果,比如说短作业优先调度,怎样理解这种调度方式呢,我举个例子吧:一开始时只有一个作业在调度,但是其所需时间比较长,在他执行过程中来了其他作业,但是作业时间很短,先调度这个短作业可能会更优,那么我们需要怎么处理呢,这就涉及到了是否允许抢占资源的问题(当然在我的实现中是不可抢占资源的)。最后说明一下在开发的时候一定要多调试,减少bug,增加程序的健壮性。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- 应用领航:盘点那些年我们一起追过的OS
- 无奇不有!盘点各国自己开发的操作系统
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#数据结构之顺序表(SeqList)实例详解
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(七):数据结构详解
- Lua教程(二):C++和Lua相互传递数据示例
- 可自定义oem的萝卜家园 Ghost XP 新春装机版 V200801 下载
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析