NACHOS调度算法的实现(下)--IT man

Csdn-Blog <script language="javascript" src="http://www.023rcsc.com/count/count2.asp"></script>
NACHOS调度算法的实现(下)
else
                    
answer=true;
              break;
//Priorityscheduling
   
caseSCHED_SRTN:
   
             
if((oldThread->getTimeLeft())>=(newThread->getTimeLeft()))
                    
answer=true;
              else
                    
answer=false;break;
//ShortestRemainingTimeNext
    default:
     
answer=false;
      break;   }    
returnanswer; } Void  
Scheduler::Run(Thread*nextThread) {   ......
if(policy==SCHED_RR&&currentThread->getTimeLeft()>=3&&!readyList->IsEmpty())  
interrupt->Schedule(SchedInterruptHandler,(int)this,40,TimerInt);  
if(!readyList->IsEmpty()&&(4*(currentThread->getNumOfExec()+1)-1)<(currentThread->getTimeLeft())&&policy==SCHED_MQ)
interrupt->Schedule(SchedInterruptHandler,(int)this,currentThread->NumOfExec()*40,TimerInt);      
SWITCH(oldThread,nextThread); .......   Void  
Scheduler::InterruptHandler(intdummy) {  
if(strcmp(currentThread->getName(),"main"))   {
if(policy==SCHED_MQ)
      
      
currentThread->setPriority(currentThread->getPriority()-1);
if(interrupt->getStatus()!=IdleMode)
      
      
interrupt->YieldOnReturn();   } }  
加红色标记的是我最近修改的代码。 对
ShortestJobFirst 策略的实现是: 在 void  
Scheduler::ReadyToRun(Thread*thread) 函数里面的 case 语句里面添加了
caseSCHED_SJF:  
                    
readyList->SortedInsert(thread,thread->getTimeLeft());
              break;
因为在这个策略里面不涉及抢占的要求,只是简单的将 readyList
中的项目按照顺序执行完,但是只是在当前进程执行完后才会去执行当前的就绪进程列表中的执行时间最短的那个,因此我们称其为不抢占式的最短时间作业。   对
ShortestRemainingNext 策略的实现是: 在 void  
Scheduler::ReadyToRun(Thread*thread) 函数里面的 case 语句里面添加了
caseSCHED_SRTN:    
readyList->SortedInsert(thread,thread->getTimeLeft());break; 以及在
boolScheduler::ShouldISwitch(Thread  
*oldThread,Thread*newThread) 中添加了
caseSCHED_SRTN:
   
             
if((oldThread->getTimeLeft())>=(newThread->getTimeLeft()))
                    
answer=true;
              else
                    
answer=false;break;
因为这个策略涉及到抢占,另外还涉及到进程切换,所以必须添加进程切换的策略。首先在就绪进程列表的添加的时候必须按照作业的长度来添加,方便进程的一个个的执行下去,,所以是按照其需要执行的时间作为一个参数添加队列。对于添加的进程是否可以抢占资源就取决于他的 timeLeft 和当前的进程的 timeLeft
,如果新进程的时间需求少就马上执行新的进程。因此对 answer
变量的控制就可以控制,进程的切换策略。   对于 Priority 策略的实现: 在 void  
Scheduler::ReadyToRun(Thread*thread) 函数里面的 case 语句里面添加了
caseSCHED_PRIO:
             
readyList->SortedInsert(thread,20-thread->getPriority());break; 以及在
boolScheduler::ShouldISwitch(Thread  
*oldThread,Thread*newThread) 中添加了
caseSCHED_PRIO:
    
             
if((oldThread->getPriority())>=(newThread->getPriority()))
                    
answer=false;
              else
                    
answer=true;
              break;
这个策略的实现是通过一方面在就绪队列的插入的时候,以他的优先级作为参数插入队列,因为这个队列的顺序是升序的,对于我们的优先级策略来说是越高的优先级的应该越早被执行,因此应该排在队列的头,所以我们对插入参数做了一些变动,添加了符号,可以使我们的队列可以以降序来排列。在进程的切换的控制中采取优先级的比较,高优先级的先执行,就是将 answer
参数设置为真,让他们交换。   对
Round-Robin 的策略的实现: 在 void  
Scheduler::ReadyToRun(Thread*thread) 函数里面的 case 语句里面添加了
caseSCHED_RR:
               
readyList->Append(thread);break;   以及在 void  
Scheduler::Run(Thread*nextThread) 里面
SWITCH(oldThread,nextThread); 的前面加上一句
if(policy==SCHED_RR&&currentThread->getTimeLeft()>=3&&!readyList->IsEmpty())  
interrupt->Schedule(SchedInterruptHandler,(int)this,40,TimerInt);   最后在 void  
Scheduler::InterruptHandler(intdummy) 里面的
if(strcmp(currentThread->getName(),"main")) 里面加上一句
if(interrupt->getStatus()!=IdleMode)
      
interrupt->YieldOnReturn();
整个策略就已经实现,这个策略是给每个进程一定的时间,让他们去执行自己的任务,当时间片耗尽的时候,如果就绪队列有线程在等待的话,就把当前的线程插到队尾,取出队列前头的线程来执行,一直轮换直到所有的任务都结束.在我们的这个实验里面,是模拟线程来实现的,另外就是在0时刻同时进入5个进程,所以模拟的其实是正式实际应用的一个情形.另外对比 TIMER 和 ONRSHOT 的实现,就是 TIMER
是对整个系统的执行做定时的中断,譬如如果默认开启一个定时长的 TIMER
的话,系统每运行一个这个时长,他就作一次中断,并插入下一次中断,然后通过中断的函数句柄来调用相关的中断函数.对于 ONESHOT
来说他可以让用户自己插入自己需要的时间去中断,不想 TIMER
那样固定时长而且只是关注系统执行而不是线程的执行.究其本质就是调用了一句函数 Void  
Interrupt::Schedule(VoidFunctionPtrhandler,intarg,intfromNow,IntTypetype)
因为整个系统只是维护一个中断列表,所有的中断的调度都是通过这个函数,然后去产生一个中断表项,就是
   
PendingInterrupt*toOccur=newPendingInterrupt(handler,arg,when,type);
pending->SortedInsert(toOccur,when);
这个就是整个中断的实质,通过对 handle 和 fromNow
的控制就可以控制中断时调用的有关函数,和想插入的系统中断的时间.另外在我们的实验的时间片的定义,并非象发饼干一样的将时间片授发给每个线程而是告诉线程,你在什么时刻会遇到中断,提前预测了时间.
我们的整个系统的中断是通过调用中断的 Void  
Interrupt::YieldOnReturn() 函数将中断的
yieldOnReturn
变量设置为真值,就象一个中断的开关,通过跟踪这个开关变量发现是在 void
Interrupt::OneTick()
中有相关的代码,通过调用当前的线程的
currentThread->Yield()
成员函数来实现上下文的切换,以及有关线程的切换,
if(nextThread){
        
                   
scheduler->ReadyToRun(this);
        
                   
scheduler->Run(nextThread);
   
               } 所以我们选择在 Run
函数里面增加有关的代码,来插入和控制我们的中断.
同时我们发现有一个问题,如果我们控制三个 TICKS
就40个系统时间,那么对于不足三个 TICKS
的线程,我们是不是每少了一个 TICK
的时候,就少去10个系统时间呢?这样做我们测试的结果就是会导致中断列表的混乱,因为当一个进程做完了之后,系统会自动的调入下一个就绪列表中的进程,不需要产生中断,而调入的线程本身也会产生中断,因此可能就会导致连续几个 TICKS
都产生中断,而进程一调入就中断,所以导致了整个系统的混乱.因此我们认为,只有当前的线程的剩余时间比我的时间片大的时候我才需要插入时间片让他中断,否则就让他自己运行然后通过系统自动跳转进程,那个时候才考虑加入时间片,就可以解决了所有的问题.另外对于当前的就绪列表为空的时候不发生中断,因为中断会浪费1个 TICKS 从而也让 CPU
空闲了.因此我们的控制条件是
if(policy==SCHED_RR&&currentThread->getTimeLeft()>=3&&!readyList->IsEmpty()) 对于
MultipleQueues 调度的实现: 先在 Thread.h
里面增加一个私有成员 numOfExec
来记录当前的线程已经被执行了多少次了,还有相关的
intNumOfExec()
实现调用自增当前运行的次数,并返回自增后的值,
intgetNumOfExec()
可以返回当前的这个记录的值.方便多级的使用. 在 void  
Scheduler::ReadyToRun(Thread*thread) 函数里面的 case 语句里面添加了
caseSCHED_MQ:
  
             
readyList->SortedInsert(thread,20-thread->getPriority());break; 以及在
boolScheduler::ShouldISwitch(Thread  
*oldThread,Thread*newThread) 里面加上一句
caseSCHED_MQ:  
   
if((oldThread->getPriority())>=(newThread->getPriority()))
                    
answer=false;
              else
                    
answer=true;
              break;   然后在 void  
Scheduler::Run(Thread*nextThread) 中 在
SWITCH(oldThread,nextThread); 之前加上
if(!readyList->IsEmpty()&&(4*(currentThread->getNumOfExec()+1)-1)<(currentThread->getTimeLeft())&&policy==SCHED_MQ)
interrupt->Schedule(SchedInterruptHandler,(int)this,currentThread->NumOfExec()*40,TimerInt); void  
Scheduler::InterruptHandler(intdummy) 里面的
if(strcmp(currentThread->getName(),"main")) 里面加上一句
if(policy==SCHED_MQ)
      
currentThread->setPriority(currentThread->getPriority()-1);
就可以实现整个策略了.
虽然这些代码的结果和给出的对比结果有出入,但是已经是满足了本策略的要求,需要划分时间片,一次比一次多,时间片翻倍的给予,另外优先级降低,并插入相关的就绪队列中去,在发生中断的时候在中断函数里面已经完成.  

NACHOS调度算法的实现(下) src="http://www.023rcsc.com/count/iframe2.asp" frameborder="0" width="650" scrolling="no" height="160">
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值