程序设计

一、数据结构

1.1 事件类型

由于要求是基于事件的进程调度,所以必须创建一个存放事件的队列。

enum EventType{ ARRIVALEVENT, FINISHEVENT, TIMEREVENT };    //事件类型

1.2 任务结构(每一项数据都是输入):

struct Job
{char name[50];       //作业名int arriveTime;      //作业到达时间int needTime;        //作业所需运行时间int priority;        //作业优先级,数字越小,优先级越高
};

1.3 事件链表结点:

struct Event
{EventType type;            //事件类型int jobBeginTime;          //作业开始时间bool isFirstExe;           //判断是否第一次执行,用于记录作业开始时间int happenTime;            //发生时刻int remainTime;            //剩余运行时间double hrr;                //最高响应比Job job;                   //作业    Event *next;               //事件指针
};

因为事件为队列存储,因而需要动态增删,所以较佳的数据结构是链表。因为是链表,所以要定义一套操作链表的函数。

二、程序流程图

2.1 非抢占式调度

2.2 抢占式调度

2.3 轮转调度

三、过程定义

3.1 事件队列相关函数

/* 作业复制函数 */
void CopyJob( Job *dest, const Job *sour );
/* 事件队列创建函数* 包含头节点* 返回头指针 */
Event *CreateEventQueue();
/* 抓取头结点之外的第一个事件* 作为返回值返回 */
Event *FetchFirstEvent( Event *head );
/* 如果值相同,时间将插在前方 */
void InsertFinishEvent( Event *head, Event *e );
/* 插入到队尾 */
void InsertTail( Event *head, Event *e );
/* 按作业名称删除第一个匹配项,* 删除成功返回TRUE,不存在该节点返回FALSE*/
bool DeleteByJobName( Event *head, char *jobName );
/* 删除事件队列 */
void DestroyQueue( Event *head );

3.2 进程调度相关函数

/* 插入函数 */
void InsertByHappenTime( Event *head, Event *e );
void InsertByJobTime( Event *head, Event *e );
void InsertByPriority( Event *head, Event *e );
void InsertByRemainTime( Event *head, Event *e );
void InsertByHRR( Event *head, Event *e );
/* 排序函数 */
void SortByHRR( Event *head, int currentTime );
/* 调度函数 */
void SJF ( Event *eventHead );
void SRTF( Event *eventHead );
void HRRF( Event *eventHead );
void Priority(Event *eventHead);    //抢占式优先级调度
void RR  ( Event *eventHead );      //时间片大小为1

程序实现

一、插入函数(用于插入排序)

1.1 按开始时间插入

void InsertByHappenTime( Event *head, Event *e )
{if ( head == NULL || e == NULL ){cerr << "At: " << __FILE__ << "\nLine: " << __LINE__ << endl;throw "Head Point is NULL!\n";}Event *p = head;while ( ( p->next != NULL ) && ( e->happenTime >= (p->next)->happenTime ) ){p = p->next;}e->next = p->next;p->next = e;
}

1.2 按结束时间插入

void InsertFinishEvent( Event *head, Event *e )
{if ( head == NULL || e == NULL ){cerr << "At: " << __FILE__ << "\nLine: " << __LINE__ << endl;throw "Head Point is NULL!\n";}Event *p = head;while ( ( p->next != NULL ) && ( e->happenTime > (p->next)->happenTime ) ){p = p->next;}e->next = p->next;p->next = e;
}

1.3 按作业时间插入

void InsertByJobTime( Event *head, Event *e )
{if ( head == NULL || e == NULL ){cerr << "At: " << __FILE__ << "\nLine: " << __LINE__ << endl;throw "Head Point is NULL!\n";}Event *p = head;while ( ( p->next != NULL ) && ( (e->job).needTime >= (p->next)->job.needTime ) ){p = p->next;}e->next = p->next;p->next = e;
}

1.4 按剩余时间插入

void InsertByRemainTime( Event *head, Event *e )
{if ( head == NULL || e == NULL ){cerr << "At: " << __FILE__ << "\nLine: " << __LINE__ << endl;throw "Head Point is NULL!\n";}Event *p = head;while ( ( p->next != NULL ) && ( e->remainTime >= p->next->remainTime ) ){p = p->next;}e->next = p->next;p->next = e;
}

1.5 按优先级插入

void InsertByPriority( Event *head, Event *e )
{if ( head == NULL || e == NULL ){cerr << "At: " << __FILE__ << "\nLine: " << __LINE__ << endl;throw "Head Point is NULL!\n";}Event *p = head;while ( ( p->next != NULL ) && ( e->job.priority >= p->next->job.priority ) ){p = p->next;}e->next = p->next;p->next = e;
}

1.6 按最高响应比插入

void InsertByHRR( Event *head, Event *e )
{if ( head == NULL || e == NULL ){cerr << "At: " << __FILE__ << "\nLine: " << __LINE__ << endl;throw "Head Point is NULL!\n";}Event *p = head;while ( ( p->next != NULL ) && ( e->hrr <= p->next->hrr ) ){p = p->next;}e->next = p->next;p->next = e;
}

1.7 最高响应比插入排序

void SortByHRR( Event *head, int currentTime )
{Event *addrValue = new Event;addrValue->next = head->next;Event *p = addrValue->next;head->next = NULL; //将节点放置另一个链表中while ( p != NULL ){p->happenTime = currentTime;p->hrr = 1 + ( p->happenTime - p->job.arriveTime ) / p->job.needTime * 0.1;p = p->next;}while ( p = FetchFirstEvent( addrValue ) ){InsertByHRR( head, p );p = addrValue->next;}delete addrValue;addrValue = NULL;
}

二、调度算法

2.1 最短工作时间优先

void SJF( Event *eventHead )
{if ( eventHead == NULL ){cerr << "At: " << __FILE__ << "\nLine: " << __LINE__ << endl;throw "Head Point is NULL!\n";}int currentTime = 0;            //当前时间bool  isCpuBusy = false;        //CPU忙碌状态Event *readyQueue = new Event;  //包含头结点,就绪队列readyQueue->next = NULL;while ( eventHead->next != NULL ){Event *firstEvent = FetchFirstEvent( eventHead );currentTime = firstEvent->happenTime;if ( firstEvent->type == ARRIVALEVENT ){if ( isCpuBusy == true ){InsertByJobTime( readyQueue, firstEvent );}else {isCpuBusy = true;Event *finishEvent = new Event;finishEvent->type = FINISHEVENT;finishEvent->jobBeginTime = currentTime;finishEvent->happenTime = currentTime + firstEvent->job.needTime;finishEvent->remainTime = 0;CopyJob( &(finishEvent->job),  &(firstEvent->job) );if ( firstEvent != NULL )delete firstEvent;//删除正在执行事件节点firstEvent = NULL;InsertByHappenTime( eventHead, finishEvent );}continue ;}if ( firstEvent->type ==  FINISHEVENT ){ShowEvent( firstEvent );if ( firstEvent != NULL )    delete firstEvent;//删除已执行事件节点firstEvent = NULL;isCpuBusy = false;Event *shortestEvent = FetchFirstEvent( readyQueue );if ( shortestEvent != NULL ){isCpuBusy = true;Event *finishEvent = new Event();finishEvent->type = FINISHEVENT;finishEvent->jobBeginTime = currentTime;finishEvent->happenTime = currentTime + shortestEvent->job.needTime;finishEvent->remainTime = shortestEvent->job.needTime;CopyJob( &(finishEvent->job),  &(shortestEvent->job) );if ( shortestEvent != NULL )    delete shortestEvent;//删除正在执行事件节点shortestEvent = NULL;InsertByHappenTime( eventHead, finishEvent );}}}
}

2.2 最短剩余时间优先

void SRTF( Event *eventHead )
{if ( eventHead == NULL ){cerr << "At: " << __FILE__ << "\nLine: " << __LINE__ << endl;throw "Head Point is NULL!\n";}int currentTime = 0;            bool  isCpuBusy = false;        Event *readyQueue = new Event;  readyQueue->next = NULL;Event *runEvent = NULL;            //正在运行事件节点while ( eventHead->next != NULL ){Event *firstEvent = FetchFirstEvent( eventHead );int frontTime = currentTime;                      //上次事件发生时间currentTime = firstEvent->happenTime;if ( firstEvent->type == ARRIVALEVENT ){if ( isCpuBusy == true ){runEvent->happenTime = currentTime;runEvent->remainTime -= (currentTime - frontTime);//剩余时间 = 运行时间- 已运行时间(本次-上次时间)if ( firstEvent->remainTime < runEvent->remainTime ){                                                        //抢断DeleteByJobName( eventHead, runEvent->job.name );    //删除上次事件的结束事件,PS.若上次事件先插入,将会被删除InsertByRemainTime( readyQueue, runEvent );          //上次事件加入就绪队列
runEvent = firstEvent;                               //上次事件已插入继续队列,无须释放空间,更新本次事件runEvent->isFirstExe = false;                        //
Event *finishEvent = new Event;                      finishEvent->type = FINISHEVENT;finishEvent->jobBeginTime = runEvent->jobBeginTime;//
                    finishEvent->happenTime = currentTime + runEvent->remainTime;finishEvent->remainTime = 0;CopyJob( &(finishEvent->job),  &(runEvent->job) );InsertByHappenTime( eventHead, finishEvent );      //插入结束事件
                }else{    InsertByRemainTime( readyQueue, firstEvent );//等待,加入就绪事件队列
                }}if ( isCpuBusy == false ){isCpuBusy = true;firstEvent->isFirstExe = false;Event *finishEvent = new Event;finishEvent->type = FINISHEVENT;finishEvent->jobBeginTime = firstEvent->jobBeginTime;    //
                finishEvent->isFirstExe = false;finishEvent->happenTime = currentTime + firstEvent->remainTime;finishEvent->remainTime = 0;CopyJob( &(finishEvent->job),  &(firstEvent->job) );runEvent = firstEvent;InsertByHappenTime( eventHead, finishEvent );}continue ;}if ( firstEvent->type ==  FINISHEVENT ){ShowEvent( firstEvent );if ( runEvent != NULL )        //删除已运行事件
                delete runEvent;runEvent = NULL;isCpuBusy = false;Event *remainTimeEvent = FetchFirstEvent( readyQueue );if ( remainTimeEvent != NULL ){isCpuBusy = true;if ( remainTimeEvent->isFirstExe )    //在就绪队列中,若作业首次执行,必然是延迟发生的remainTimeEvent->jobBeginTime = currentTime;remainTimeEvent->isFirstExe = false;Event *finishEvent = new Event();finishEvent->type = FINISHEVENT;finishEvent->jobBeginTime = remainTimeEvent->jobBeginTime;finishEvent->happenTime = currentTime + remainTimeEvent->remainTime;finishEvent->remainTime = 0;CopyJob( &(finishEvent->job),  &(remainTimeEvent->job) );runEvent = remainTimeEvent;       InsertByHappenTime( eventHead, finishEvent );}}}
}

2.3 时间片轮转(时间片大小为1)

void RR( Event *eventHead )
{if ( eventHead == NULL ){cerr << "At: " << __FILE__ << "\nLine: " << __LINE__ << endl;throw "Head Point is NULL!\n";}int currentTime = 0;bool isCpuBusy = false;Event *readyQueue = new Event;readyQueue->next = NULL;while ( eventHead->next != NULL ){    Event *firstEvent = FetchFirstEvent( eventHead );if ( firstEvent->happenTime > currentTime )currentTime = firstEvent->happenTime;if ( firstEvent->type == ARRIVALEVENT ){if ( isCpuBusy ){InsertTail( readyQueue, firstEvent );}else{    isCpuBusy = true;Event *nextEvent = new Event;nextEvent->jobBeginTime = firstEvent->jobBeginTime;CopyJob( &(nextEvent->job),  &(firstEvent->job) );if ( firstEvent->remainTime <= TIMER )    //FinishEvent
                {nextEvent->type = FINISHEVENT;nextEvent->happenTime = currentTime + firstEvent->remainTime;nextEvent->remainTime = 0;    InsertFinishEvent( eventHead, nextEvent );}else    //TimerEvent
                {nextEvent->type = TIMEREVENT;nextEvent->happenTime = currentTime + TIMER;nextEvent->remainTime = firstEvent->remainTime - TIMER;InsertByHappenTime( eventHead, nextEvent );}if ( firstEvent != NULL )delete firstEvent;//删除正在执行事件节点firstEvent = NULL;}continue ;}if ( firstEvent->type == TIMEREVENT ){InsertTail( readyQueue, firstEvent );}int isFinish = false;if ( firstEvent->type ==  FINISHEVENT ){ShowEvent( firstEvent );if ( firstEvent != NULL )    delete firstEvent;//删除已执行事件节点firstEvent = NULL;isFinish = true;}while ( firstEvent = FetchFirstEvent( readyQueue ) ){if ( isFinish )isCpuBusy = true, isFinish = false;Event *nextEvent = new Event;if ( firstEvent->type == ARRIVALEVENT )nextEvent->jobBeginTime = currentTime;else if ( firstEvent->type == TIMEREVENT )nextEvent->jobBeginTime = firstEvent->jobBeginTime;CopyJob( &(nextEvent->job),  &(firstEvent->job) );if ( firstEvent->remainTime <= TIMER )    //FinishEvent
            {nextEvent->type = FINISHEVENT;nextEvent->happenTime = currentTime + firstEvent->remainTime;nextEvent->remainTime = 0;InsertFinishEvent( eventHead, nextEvent );}else    //TimerEvent
            {    nextEvent->type = TIMEREVENT;nextEvent->happenTime = currentTime + TIMER;nextEvent->remainTime = firstEvent->remainTime - TIMER;InsertByHappenTime( eventHead, nextEvent );}currentTime = nextEvent->happenTime;if ( firstEvent != NULL )delete firstEvent;//删除正在执行事件节点firstEvent = NULL;}}
}

2.4 抢占式优先级调度

void Priority( Event *eventHead )
{if ( eventHead == NULL ){cerr << "At: " << __FILE__ << "\nLine: " << __LINE__ << endl;throw "Head Point is NULL!\n";}int currentTime = 0;            bool  isCpuBusy = false;        Event *readyQueue = new Event;  readyQueue->next = NULL;Event *runEvent = NULL;            //正在运行事件节点while ( eventHead->next != NULL ){Event *firstEvent = FetchFirstEvent( eventHead );int frontTime = currentTime;                      //上次事件发生时间currentTime = firstEvent->happenTime;if ( firstEvent->type == ARRIVALEVENT ){if ( isCpuBusy == true ){runEvent->happenTime = currentTime;runEvent->remainTime -= (currentTime - frontTime);//剩余时间 = 运行时间- 已运行时间(本次-上次时间)if ( firstEvent->job.priority < runEvent->job.priority ){                                                      //抢断DeleteByJobName( eventHead, runEvent->job.name ); //删除上次事件的结束事件,PS.若上次事件先插入,将会被删除InsertByPriority( readyQueue, runEvent );          //上次事件加入就绪队列
                    runEvent = firstEvent;                              //上次事件已插入继续队列,无须释放空间,更新本次事件runEvent->isFirstExe = false;                      //
                    Event *finishEvent = new Event;                      finishEvent->type = FINISHEVENT;finishEvent->jobBeginTime = runEvent->jobBeginTime;//
                    finishEvent->happenTime = currentTime + runEvent->remainTime;finishEvent->remainTime = 0;CopyJob( &(finishEvent->job),  &(runEvent->job) );InsertByHappenTime( eventHead, finishEvent );      //插入结束事件
                }else{    InsertByRemainTime( readyQueue, firstEvent );//等待,加入就绪事件队列
                }}if ( isCpuBusy == false ){isCpuBusy = true;firstEvent->isFirstExe = false;Event *finishEvent = new Event;finishEvent->type = FINISHEVENT;finishEvent->jobBeginTime = firstEvent->jobBeginTime;    finishEvent->happenTime = currentTime + firstEvent->remainTime;finishEvent->remainTime = 0;CopyJob( &(finishEvent->job),  &(firstEvent->job) );runEvent = firstEvent;InsertByHappenTime( eventHead, finishEvent );}continue ;}if ( firstEvent->type ==  FINISHEVENT ){ShowEvent( firstEvent );if ( runEvent != NULL )        //删除已运行事件
                delete runEvent;runEvent = NULL;isCpuBusy = false;Event *priorityEvent = FetchFirstEvent( readyQueue );if ( priorityEvent != NULL ){isCpuBusy = true;if ( priorityEvent->isFirstExe )    //在就绪队列中,若作业首次执行,必然是延迟发生的priorityEvent->jobBeginTime = currentTime;Event *finishEvent = new Event();finishEvent->type = FINISHEVENT;finishEvent->jobBeginTime = priorityEvent->jobBeginTime;finishEvent->happenTime = currentTime + priorityEvent->remainTime;finishEvent->remainTime = 0;CopyJob( &(finishEvent->job),  &(priorityEvent->job) );runEvent = priorityEvent;InsertByHappenTime( eventHead, finishEvent );}}}
}

2.5 最高响应比优先

void HRRF( Event *eventHead )
{if ( eventHead == NULL ){cerr << "At: " << __FILE__ << "\nLine: " << __LINE__ << endl;throw "Head Point is NULL!\n";}int currentTime = 0;            //当前时间bool  isCpuBusy = false;        //CPU忙碌状态Event *readyQueue = new Event;  //包含头结点,就绪队列readyQueue->next = NULL;while ( eventHead->next != NULL ){Event *firstEvent = FetchFirstEvent( eventHead );currentTime = firstEvent->happenTime;if ( firstEvent->type == ARRIVALEVENT ){if ( isCpuBusy == true ){InsertTail( readyQueue, firstEvent ); }else {isCpuBusy = true;Event *finishEvent = new Event;finishEvent->type = FINISHEVENT;finishEvent->jobBeginTime = currentTime;finishEvent->happenTime = currentTime + firstEvent->job.needTime;finishEvent->remainTime = 0;CopyJob( &(finishEvent->job),  &(firstEvent->job) );if ( firstEvent != NULL )delete firstEvent;//删除正在执行事件节点firstEvent = NULL;InsertByHappenTime( eventHead, finishEvent );}continue ;}if ( firstEvent->type ==  FINISHEVENT ){ShowEvent( firstEvent );if ( firstEvent != NULL )    delete firstEvent;//删除已执行事件节点firstEvent = NULL;isCpuBusy = false;SortByHRR( readyQueue, currentTime );Event *hrrEvent = FetchFirstEvent( readyQueue );if ( hrrEvent != NULL ){isCpuBusy = true;Event *finishEvent = new Event();finishEvent->type = FINISHEVENT;finishEvent->jobBeginTime = currentTime;finishEvent->happenTime = currentTime + hrrEvent->job.needTime;finishEvent->remainTime = hrrEvent->job.needTime;CopyJob( &(finishEvent->job),  &(hrrEvent->job) );if ( hrrEvent != NULL )    delete hrrEvent;//删除正在执行事件节点hrrEvent = NULL;InsertByHappenTime( eventHead, finishEvent );}}}
}

测试数据

进程

到达时间

服务时间

优先级

A

0

3

5

B

2

6

2

C

4

4

3

D

6

5

4

E

8

2

1

运行结果

一、最短作业时间优先

二、最短剩余时间优先

三、最高响应比优先

四、优先级调度

五、时间片轮转

时间片=1

时间片=4

总结与体会

根据流程图,一步一步实现功能,思路清晰,就不会出错。PS:C#程序的可视化及其调度算法采用LINQ实现,将在下章讲解。

转载于:https://www.cnblogs.com/bajdcc/p/4707746.html

五种进程调度的算法实现(二)相关推荐

  1. 机器学习--聚类(五种主要聚类算法)

    机器学习–聚类(五种主要聚类算法) 原博文: 聚类是一种机器学习技术,它涉及到数据点的分组.给定一组数据点,我们可以使用聚类算法将每个数据点划分为一个特定的组.理论上,同一组中的数据点应该具有相似的属 ...

  2. 五种内部排序算法性能比较——C++

    **五种内部排序算法性能比较 ** 1.直接插入排序算法 将一个待排序的记录插入到若干个已排好序的有序记录中的适当位置,从而得到一个新的.记录数增加1的有序数据序列,直到插入完成.在最开始,整个有序数 ...

  3. 五种常用排序算法总结

    本篇文章讲的是以下五种常用的排序算法: 一.冒泡排序 1.原理 每次从前往后遍历整个数组,每一项与其后一项进行对比,若符合要求(从大到小或从小到大),就交换位置. 一遍循环结束后,最大(小)的值就会被 ...

  4. 对比IRLS,OMP,MOMP,SP以及CoSaMP五种压缩感知算法的信号重构性能

    UP目录 一.理论基础 1.1IRLS 1.2OMP 1.3SP 1.4CoSaMP 二.核心程序 三.测试结果 一.理论基础 压缩采样匹配追踪(CompressiveSampling MP)是D. ...

  5. 【聚类】五种主要聚类算法

    原博文: 聚类是一种机器学习技术,它涉及到数据点的分组.给定一组数据点,我们可以使用聚类算法将每个数据点划分为一个特定的组.理论上,同一组中的数据点应该具有相似的属性和/或特征,而不同组中的数据点应该 ...

  6. 我总结了五种常用聚类分析算法,推荐收藏

    大量数据中具有"相似"特征的数据点或样本划分为一个类别.聚类分析提供了样本集在非监督模式下的类别划分. 基本思想 物以类聚.人以群分 常用于数据探索或挖掘前期 没有先验经验做探索性 ...

  7. 理论+股市数据实战,总结了五种常用聚类分析算法

    来源:数据STUDIO 大量数据中具有"相似"特征的数据点或样本划分为一个类别.聚类分析提供了样本集在非监督模式下的类别划分. 基本思想 物以类聚.人以群分 常用于数据探索或挖掘前 ...

  8. [ Android 五种数据存储方式之二 ] —— 文件存储数据

    关于文件存储,Activity提供了openFileOutput()方法可以用于把数据输出到文件中,具体的实现过程与在J2SE环境中保存数据到文件中是一样的. 文件可用来存放大量数据,如文本.图片.音 ...

  9. HTML的五种经典布局方式(二)

    三.flex布局(弹性布局) "弹性布局",用来为盒装模型提供最大的灵活性.采用Flex布局的元素,称为Flex容器(flex container),简称"容器" ...

  10. 概率论基础(4)五种重要的分布(二项、泊松、均匀、指数、正态分布)

    概率论对于学习 NLP 方向的人,重要性不言而喻.于是我打算从概率论基础篇开始复习,也顺便巩固巩固基础. 这是基础篇的第四篇知识点总结 基础:下面前三篇的链接地址: 概率论基础(1)古典和几何概型及事 ...

最新文章

  1. Stream流与Lambda表达式(一) 杂谈
  2. Java黑皮书课后题第4章:*4.6(图上的随机点)编写一个程序,产生一个圆心位于(0,0)原点半径为40的圆上面的三个随机点,显示由这三个随机点组成的三角形的三个角的度数
  3. TCP IP基础知识的复习
  4. php基础开发(集成环境搭建)
  5. ASP.NET状态管理之五(Cookie)
  6. Office online server 部署
  7. 南京师范大学计算机科学与技术复试名单,2018年各学院硕士研究生复试办法及复试名单公示网址汇总表...
  8. Powershell基本命令总结(更新中)
  9. 这打车App麻烦了!遭黑客勒索巨额比特币
  10. delphi7 增加管理员权限_EHR系统的权限设计
  11. ***工具XSCAN V3.3 GUI的使用
  12. php 四叉树quadtree,线性四叉树十进制编码原理 四叉树(Quadtrees)一共有多少种?...
  13. 【c语言大作业】c语言编写贪吃蛇
  14. 我的保研之路-哈工大计算机,中科院信工所,复旦大数据学院
  15. PS后期一键调出紫色梦幻红外线照片效果
  16. 第三章 栈和队列(含答案)
  17. 投影幕布必备知识有哪些?
  18. 使用PS实现简单的名片制作
  19. 分析师意外下调评级为中性,苹果财报能否改变科技股走向?
  20. 电脑配件 - 如何选择电脑显示屏幕 - 学习/实践

热门文章

  1. 最大似然估计、MAP及贝叶斯估计
  2. 101与金根回顾敏捷个人:(82)《把时间当做朋友》
  3. Codeforces Round #484 (Div. 2) D. Shark
  4. Web API 路由 [二] Attribute Routing
  5. Python3之logging模块
  6. 题目1012:畅通工程(并查集)
  7. SQL 数据库 函数
  8. oracle 用户被锁定解决方法
  9. tomcat登录账户配置
  10. Java 动态绑定/多态