码迷,mamicode.com
首页 > 编程语言 > 详细

五种进程调度的算法实现(二)

时间:2015-08-06 14:54:15      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:

程序设计

一、数据结构

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实现,将在下章讲解。

五种进程调度的算法实现(二)

标签:

原文地址:http://www.cnblogs.com/bajdcc/p/4707746.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!