操作系统进程调度算法模拟运行

一、简介

1、此为计算机系统能力实训选题之一,具体实现时间片轮转算法、优先级算法、高响应比算法和多级反馈队列算法这四种调度算法。四种算法的知识点不多赘述。
2、不同于之前的控制台输入,这次我受一位博主启发,使用GUI功能模拟了四种调度算法的动态过程,与动画还是有很大差距,但相比之前更加形象直观,。
3、本想实现更友好化的界面,奈何能力、时间有限,很多想法没能实现,比如如何加上滚动条,给优先级算法和多级反馈队列算法加上到达时间等等,欢迎完善。

二、核心函数代码

1、时间片轮转算法

 public static void startRRSimulation()
    {
        isStopScheduling = false;

        //更新界面操作必须借助多线程来实现
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                //当前内存中还留有进程未执
                while(currentPCBsNum!=0 && !isStopScheduling)
                {                	                	                                                                                                                                      	
                	
                    LinkedList<PCB> queue1 = PCBsQueues[3].getQueue();//UnArrive队列
                                                           
                    LinkedList<PCB> queue3 = PCBsQueues[4].getQueue();//Running队列
                    
                    Collections.sort(queue1, new compareArrive());//对UnArrive队列按照到达时间升序排队
                                                                                               
                    textArea.setText(String.valueOf(nowTime));//用于在时钟对应位置展示此时的nowTime,即当前时间
                    boolean flag = true;//标志
                    while((queue1.size()>0)&&(flag)) {//UnArrive队列非空且flag为true
                    	
                    	flag=false;//设置flag为false
                    	  PCB pcb1 = queue1.element();//获取UnArrive队列第一个进程
                    	  if(pcb1.getarriveTime()<=nowTime) {//判断进程是否已经到达                      		 
                    		  queue1.poll();                 //若到达,则将进程从UnArrive队列删除      	
                    		  pcb1.setStatus("Ready");    //设置进程状态为Ready                    		 
                    		  queue3.offer(pcb1);            //将进程添加到Ready队列            		 
                    		  flag=true;                     //flag设为true,表示进程进入过该if选择语句
                    		 
                    	  }  //因为UnArrive队列已经按照到达时间排序,所以一旦UnArrive队列队列首个元素都未到达,后边进程不必再判断,无法进入if选择语句,flag无法变为true,while循环结束                                    	
                    }
                    PCBsQueues[3].setQueue(queue1);//将UnArrive队列放回队列组
                    PCBsQueues[4].setQueue(queue3);//将Running队列放回队列组
                    showPCBQueues(PCBsQueues);//展示进程剩余服务时间变化
                                                                                                                     	
                    if(queue3.size()>0) //Running队列不为空
                    {
                	                   	                   	   
                	    PCB pcb3=queue3.element();//获取Running队列第一个进程               	                  	    
                	    pcb3.setStatus("Running");
                	    PCBsQueues[3].setQueue(queue1);//将UnArrive队列放回队列组
     	                PCBsQueues[4].setQueue(queue3);//将Running队列放回队列组
     	                showPCBQueues(PCBsQueues);//展示进程剩余服务时间变化
     	                    
     	                int pid=pcb3.getPid();//获取进程ID
     	                   	     	                   	
     	                float temp3=pcb3.getSurplusServeTime()-1;//再减去等待时间,即为该进程的已运行时间     	                   	
     	                   	
     	                pcb3.setSurplusServeTime(temp3);//设置进程的剩余服务时间
     	                    
    	                try
    	                {   	                	
    	                    Thread.sleep((int)(1 * 5000));//每次循环sleep一个时间片的时间
    	                }
    	                catch (InterruptedException e)
    	                {
    	                    e.printStackTrace();
    	                }
     	                   	
     	                if(temp3<=0) {//剩余服务时间小于0,即运行结束
     	                   		
     	                   	queue3.poll();//删除该进程
     	                    pidsUsed[pid] = 0;//设置该进程ID未使用
     	                    currentPCBsNum--;//进程数减1
     	                               	                           
                	    }else {
                	    	pcb3.setStatus("Ready");
                	    	queue3.poll();//删除Running队列第一个进程
                	    	queue3.offer(pcb3);//添加至队尾
                	    	showPCBQueues(PCBsQueues);//展示进程剩余服务时间变化
                	    }
     	                    
                	   
                    }else {
                	   try
	                    {
	                        Thread.sleep((int)(1 * 5000));//每次循环sleep一个时间片的时间
	                    }
	                    catch (InterruptedException e)
	                    {
	                        e.printStackTrace();
	                    }
                   }
                   
                    PCBsQueues[3].setQueue(queue1);//将UnArrive队列放回队列组
                    PCBsQueues[4].setQueue(queue3);//将Running队列放回队列组
                    showPCBQueues(PCBsQueues);//展示进程剩余服务时间变化
                	   
                	
                    
                    nowTime=nowTime+1;//当前时间加1,表示时钟走过一秒
                    textArea.setText(String.valueOf(nowTime));//用于在时钟对应位置展示此时的nowTime,即当前时间
                                                                                                                                                                                 
                }

                
                initMemory();//初始化内存
                showPCBQueues(PCBsQueues);
                //有进程均执行完成,进程调度完
                JOptionPane.showMessageDialog(frame, "进程调度完成!");
                //frame.dispose();
            }
        }).start();

    }

2、优先级调度算法

 public static void startPSA()
    {
        isStopScheduling = false;

        //更新界面操作必须借助多线程来实现
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                //当前内存中还留有进程未执行
                while(currentPCBsNum!=0 && !isStopScheduling)
                {
                	textArea.setText(String.valueOf(nowTime));//用于在时钟对应位置展示此时的nowTime,即当前时间
                    for(int i = PCBsQueues.length - 1; i >= 0; i--)//每次按优先级由高到低取队列组的队列
                    {
                        LinkedList<PCB> queue = PCBsQueues[i].getQueue();

                        if (queue.size() > 0)//队列不为空
                        {
                           
                            PCB pcb = queue.element(); //读取该队列首个PCB
                            pcb.setStatus("Running");//设置状态为Running
                            showPCBQueues(PCBsQueues);

                            int pid = pcb.getPid();//获得进程ID
                            int priority = pcb.getPriority();//获得进程优先级
                          
                            float SurplusServeTime=pcb.getSurplusServeTime();//获得进程剩余服务时间
                         
                            priority = priority-1;//优先级减1
                            
                           if(SurplusServeTime>1) {//剩余服务时间大于1个时间片
                        	   try
                               {
                                   Thread.sleep((int)(1 * 2000));//每次循环sleep一个时间片的时间
                               }
                               catch (InterruptedException e)
                               {
                                   e.printStackTrace();
                               }
                        	   SurplusServeTime--;//剩余服务时间减1
                               pcb.setSurplusServeTime(SurplusServeTime);//更新进程的剩余服务时间
                           }
                           else {//剩余服务时间不止一个时间片
                        	   try
                               {
                                   Thread.sleep((int)(SurplusServeTime * 2000));//每次循环sleep一个时间片的时间
                               }
                               catch (InterruptedException e)
                               {
                                   e.printStackTrace();
                               }
                        	   //移除该队列的首个PCB
                               queue.poll();
                               pidsUsed[pid] = 0;//更新进程使用数组
                               currentPCBsNum--;//内存中进程数减1
                           }
                            
                           nowTime++;//时钟+1,同步变化
                           textArea.setText(String.valueOf(nowTime));//用于在时钟对应位置展示此时的nowTime,即当前时间
                            break;
                        }
                    }
                   // nowTime++;
                }

                initMemory();
                showPCBQueues(PCBsQueues);
                //有进程均执行完成,进程调度完
                JOptionPane.showMessageDialog(frame, "进程调度完成!");
                //frame.dispose();
            }
        }).start();

    }

3、高响应比调度算法

public static void startHRRN()
    {
        isStopScheduling = false;

        //更新界面操作必须借助多线程来实现
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                //当前内存中还留有进程未执
                while(currentPCBsNum!=0 && !isStopScheduling)
                {
                	   
                	    
                    
                	//此算法需要三个队列,分别是UnArrive队列,Waitting队列,和Running队列
                        LinkedList<PCB> queue1 = PCBsQueues[2].getQueue();//UnArrive队列
                        
                        LinkedList<PCB> queue2 = PCBsQueues[3].getQueue();//Waitting队列
                        
                        LinkedList<PCB> queue3 = PCBsQueues[4].getQueue();//Running队列
                        
                        Collections.sort(queue1, new compareArrive());//对UnArrive队列按照到达时间升序排队
                                                                  
                       
                        Collections.sort(queue2, new compareHRR());//对Waitting队列按照响应比降序排序
                       
                        textArea.setText(String.valueOf(nowTime));//用于在时钟对应位置展示此时的nowTime,即当前时间
                        boolean flag = true;//标志
                        while((queue1.size()>0)&&(flag)) {//UnArrive队列非空且flag为true
                        	
                        	flag=false;//设置flag为false
                        	  PCB pcb1 = queue1.element();//获取UnArrive队列第一个进程
                        	  if(pcb1.getarriveTime()<=nowTime) {//判断进程是否已经到达                      		 
                        		  queue1.poll();                 //若到达,则将进程从UnArrive队列删除      	
                        		  pcb1.setStatus("Waitting");    //设置进程状态为Waitting                    		 
                        		  queue2.offer(pcb1);            //将进程添加到Waitting队列            		 
                        		  flag=true;                     //flag设为true,表示进程进入过该if选择语句
                        	  }  //因为UnArrive队列已经按照到达时间排序,所以一旦UnArrive队列队列首个元素都未到达,后边进程不必再判断,无法进入if选择语句,flag无法变为true,while循环结束                                    	
                        }
                        
                      
                        Collections.sort(queue2, new compareHRR());//对Waitting队列再次按照响应比排序
                        
                        
                        
                        if(queue2.size()>0) {//如果Waitting队列不为空
                        	if(queue3.size()==0) {//Running队列为空
                            	
                            	
                            	  PCB pcb3 = queue2.element();//获取Waitting队列第一个进程
                            	  queue2.poll();//删除该进程
                            	  pcb3.setStatus("Running");//设置进程状态为Running
                            	  float temp=nowTime-pcb3.getarriveTime();//根据当前时间和到达时间之差计算等待时间
                            	  pcb3.setwaitTime(temp);//设置等待时间
                            	 
                                  queue3.offer(pcb3);//将进程添加到Running队列运行
                                
                            }
                            else //Running队列不为空
                            {
                            	                            	
                            	PCB pcb3=queue3.element();//获取Running队列第一个进程
                            	int pid=pcb3.getPid();//获取进程ID
                            	float temp1=nowTime-pcb3.getarriveTime();//当前时间减去到达时间
                            	float temp2=temp1-pcb3.getwaitTime();//再减去等待时间,即为该进程的已运行时间
                            	float temp3=pcb3.getserveTime()-temp2;//进程总服务时间减去已运行时间,获得进程剩余服务时间
                            	pcb3.setSurplusServeTime(temp3);//设置进程的剩余服务时间
                            	
                            	
                            	
                            	if(temp3<=0) {//剩余服务时间小于0,即运行结束
                            		queue3.poll();//删除该进程
                                    pidsUsed[pid] = 0;//设置该进程ID未使用
                                    currentPCBsNum--;//进程数减1
                                    PCB pcb4=queue2.element();//获得Waitting队列第一个进程
                                    queue2.poll();//删除该进程
                              	    pcb4.setStatus("Running");//设置运行状态
                              	    float temp=nowTime-pcb4.getarriveTime();//计算等待时间
                              	    pcb4.setwaitTime(temp);//设置等待时间
                              	    queue3.offer(pcb4);//将该进程添加到Running队列队尾
                            	}
                            	
                            }
                        }
                        else {//如果Waitting队列为空
                        	if(queue3.size()>0) {//Running队列不为空
                        		PCB pcb3=queue3.element();//获取Running队列第一个进程
                            	int pid=pcb3.getPid();//获取进程ID
                            	float temp1=nowTime-pcb3.getarriveTime();//当前时间减去到达时间
                            	float temp2=temp1-pcb3.getwaitTime();//再减去等待时间,即为该进程的已运行时间
                            	float temp3=pcb3.getserveTime()-temp2;//进程总服务时间减去已运行时间,获得进程剩余服务时间
                            	pcb3.setSurplusServeTime(temp3);//设置进程的剩余服务时间
                            	
                            	
                            	
                            	if(temp3<=0) {//剩余服务时间为小于0,即运行结束
                            		queue3.poll();//删除该进程
                                    pidsUsed[pid] = 0;//设置该进程ID未使用
                                    currentPCBsNum--;//进程数减1
                                    
                            	}
                        	}
                        }
                       
                        
                        PCBsQueues[2].setQueue(queue1);//将UnArrive队列放回队列组
                        PCBsQueues[3].setQueue(queue2);//将Waitting队列放回队列组
                        PCBsQueues[4].setQueue(queue3);//将Running队列放回队列组
                        showPCBQueues(PCBsQueues);
                        
                        
                        if(currentPCBsNum==0) {
                        	break;//内存内无进程,跳出while循环
                        }
                        
                        try
                        {
                            Thread.sleep((int)(1 * 5000));//每次循环sleep一个时间片的时间
                        }
                        catch (InterruptedException e)
                        {
                            e.printStackTrace();
                        }
                        
                        nowTime=nowTime+1;//当前时间加1,表示时钟走过一秒
                                                                     
                }               
                initMemory();//内存初始化
                
                showPCBQueues(PCBsQueues);//展示队列组
                //有进程均执行完成,进程调度完
                JOptionPane.showMessageDialog(frame, "进程调度完成!");
                //frame.dispose();
            }
        }).start();

    }

4、多级反馈队列调度算法

 public static void startMFQ()
    {
        isStopScheduling = false;

        //更新界面操作必须借助多线程来实现
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                //当前内存中还留有进程未执行
                while(currentPCBsNum!=0 && !isStopScheduling)
                {
                	textArea.setText(String.valueOf(nowTime));//用于在时钟对应位置展示此时的nowTime,即当前时间
                    for(int i = PCBsQueues.length - 1; i >= 0; i--)//因队列组的优先级随下标的增加而增加,故从后往前取队列执行操作
                    {
                        LinkedList<PCB> queue = PCBsQueues[i].getQueue();//取对应下标的队列出来

                        
                        //LinkedList<PCB> Nextqueue = PCBsQueues[i-1].getQueue();//取对应下标的队列出来
                        
                        
                        if (queue.size() > 0)//如果队列有进程,则执行
                        {
                            
                            PCB pcb = queue.element(); //读取该队列首个PCB
                           
                            pcb.setStatus("Running");//设置为运行状态
                            showPCBQueues(PCBsQueues);//通过展示函数展示PCB的必要信息

                            int pid = pcb.getPid();//获得PCB的ID
                            int priority = pcb.getPriority();//获得PCB的优先级
                            
                            float SurplusServeTime=pcb.getSurplusServeTime();//获得PCB的剩余服务时间
                           
                            priority = priority-1;//进程已经开始执行,优先级减一
                            

                           if(priority==-1) 
                           {    //这里讨论当前执行的队列是不是最后一个队列,也就是优先级为0的队列,如果是那么剩下的未执行的进程会按照时间片轮转算法执行
                        	  
                               if(SurplusServeTime<=PCBsQueuesTimeSlice[i]) //若该进程剩余服务时间小于时间片
                               {
                            	   while(SurplusServeTime>0) {//剩余服务时间大于0,则循环。用于在进程剩余服务时间小于时间片时,将进程的剩余服务时间执行完
                            		   if(isStopScheduling) {//用于调度结束函数判断
                            			   break;
                            		   }
                            		   try//通过sleep函数模拟进程调度所需要的时间
                                       {
                                           Thread.sleep((int)(1 * 4000));//如果剩余服务时间小于时间片,那么sleep剩余服务时间大小的时间
                                       }
                                       catch (InterruptedException e)
                                       {
                                           e.printStackTrace();
                                       }
                            		   SurplusServeTime--;//每循环一次,剩余服务时间减1
                            		   pcb.setSurplusServeTime(SurplusServeTime);//设置pcb剩余服务时间                           		                               		                                          
                                       PCBsQueues[i].setQueue(queue);//将队列放置回队列组
                                       showPCBQueues(PCBsQueues);//展示队列组信息,体现进程剩余服务时间在递减的动态变化
                            		   nowTime++;//当前时间递增
                            		   textArea.setText(String.valueOf(nowTime));//用于在时钟对应位置展示此时的nowTime,即当前时间
                            	   }                           	                                	                               	 
                                   queue.poll();移除该队列的首个PCB
                                   pidsUsed[pid] = 0;//此数组记录进程是否被创建,创建则为1,未创建则为0,因为此进程执行结束,所以把数组中该ID对应的数值设为0.表示内存中无此ID的进程了
                                   currentPCBsNum--;//内存进程数减1
                               }
                               else//若该进程剩余服务时间大于时间片
                               {
                            	   double temp=PCBsQueuesTimeSlice[i];//用中间值表示需运行的时间片
                            	   while(temp>0) {//运行时间片,直至为0,跳出while循环
                            		   if(isStopScheduling) {//用于调度结束函数判断
                            			   break;
                            		   }
                            		   try
                                       {
                                           Thread.sleep((int)(1 * 4000));//如果剩余服务时间大于时间片,那么sleep剩余时间片大小的时间
                                       }
                                       catch (InterruptedException e)
                                       {
                                           e.printStackTrace();
                                       }
                            		   temp--;//需运行时间片减1
                            		   SurplusServeTime--;//每循环一次,剩余服务时间减1
                            		   pcb.setSurplusServeTime(SurplusServeTime); //设置pcb剩余服务时间                            		                                                                               
                                       PCBsQueues[i].setQueue(queue);//将队列放置会队列组
                                       showPCBQueues(PCBsQueues);//展示队列组信息,体现进程剩余服务时间在递减的动态变化
                            		   nowTime++;//当前时间递增
                            		   textArea.setText(String.valueOf(nowTime));//用于在时钟对应位置展示此时的nowTime,即当前时间
                            	   }
                            	   
                            	   //SurplusServeTime=(float) (SurplusServeTime-PCBsQueuesTimeSlice[i]);//剩余服务时间减去时间片
                            
                                   queue.poll(); //移除该队列的首个PCB

                                   pcb.setPriority(priority+1);//之前减了1,优先级变成了-1,此时加上1,优先级变为0,表示还是最后一个队列
                                   pcb.setSurplusServeTime(SurplusServeTime);//设置剩余服务时间
                                   pcb.setStatus("Ready");//设置状态为ready
                                   //LinkedList<PCB> Queue = PCBsQueues[i].getQueue();//获得该优先级最低的队列,也就是此队列
                                   queue.offer(pcb);//将未执行完的进程添加到队尾
                                   PCBsQueues[0].setQueue(queue);//将队列放置会队列组
                                   showPCBQueues(PCBsQueues);//展示队列组信息,体现进程剩余服务时间在递减的动态变化
                               }
                           }
                           else//如果此队列不是优先级最小的队列
                           {
                        	   
                               if(SurplusServeTime<=PCBsQueuesTimeSlice[i])//若该进程剩余服务时间小于时间片
                               {
                            	   while(SurplusServeTime>0) {//剩余服务时间大于0,则循环。用于在进程剩余服务时间小于时间片时,将进程的剩余服务时间执行完
                            		   if(isStopScheduling) {//用于调度结束函数判断
                            			   break;
                            		   }
                            		   try//通过sleep函数模拟进程调度所需要的时间
                                       {
                                           Thread.sleep((int)(1 * 4000));//如果剩余服务时间小于时间片,那么sleep剩余服务时间大小的时间
                                       }
                                       catch (InterruptedException e)
                                       {
                                           e.printStackTrace();
                                       }
                            		   SurplusServeTime--;//每循环一次,剩余服务时间减1
                            		   pcb.setSurplusServeTime(SurplusServeTime); //设置pcb的剩余服务时间                          		                               		                                          
                                       PCBsQueues[i].setQueue(queue);//将队列放置会队列组
                                       showPCBQueues(PCBsQueues);//展示队列组信息,体现进程剩余服务时间在递减的动态变化
                            		   nowTime++;//当前时间递增
                            		   textArea.setText(String.valueOf(nowTime));//用于在时钟对应位置展示此时的nowTime,即当前时间 
                            	   }                            	                                 	                              	
                                   queue.poll(); //移除该队列的首个PCB
                                   pidsUsed[pid] = 0;//此数组记录进程是否被创建,创建则为1,未创建则为0,因为此进程执行结束,所以把数组中该ID对应的数值设为0.表示内存中无此ID的进程了
                                   currentPCBsNum--;//内存进程数减1
                               }
                               else//若该进程剩余服务时间大于时间片
                               {
                            	   double temp=PCBsQueuesTimeSlice[i];//用中间值表示需运行的时间片
                            	   while(temp>0) {//运行时间片,直至为0,跳出while循环
                            		   if(isStopScheduling) {//用于调度结束函数判断
                            			   break;
                            		   }
                            		   try
                                       {
                                           Thread.sleep((int)(1 * 4000));//如果剩余服务时间大于时间片,那么sleep剩余时间片大小的时间
                                       }
                                       catch (InterruptedException e)
                                       {
                                           e.printStackTrace();
                                       }
                            		   temp--;//需运行时间片减1
                            		   SurplusServeTime--;//每循环一次,剩余服务时间减1
                            		   pcb.setSurplusServeTime(SurplusServeTime);    //设置pcb的剩余运行时间                       		                                                                               
                                       PCBsQueues[i].setQueue(queue);//将队列放置回队列组
                                       if(temp!=0) {
                                    	   showPCBQueues(PCBsQueues);
                                       }
                                       //showPCBQueues(PCBsQueues);
                            		   nowTime++;//当前时间加1
                            		   textArea.setText(String.valueOf(nowTime));//用于在时钟对应位置展示此时的nowTime,即当前时间
                            	   }
                            	  
                            	   //SurplusServeTime=(float) (SurplusServeTime-PCBsQueuesTimeSlice[i]);//剩余服务时间减去时间片
                            
                                   
                                   queue.poll();//移除该队列的首个PCB

                                   pcb.setPriority(priority);//设置队列优先级
                                   pcb.setSurplusServeTime(SurplusServeTime);//设置队列的剩余服务时间
                                   pcb.setStatus("Ready");//设置状态为ready
                                   LinkedList<PCB> nextQueue = PCBsQueues[i-1].getQueue();//此处取得优先级低一等级的队列,也就是把未执行完的队列添加到下一级队列的队尾
                                   nextQueue.offer(pcb);//把未执行完的队列添加到下一级队列的队尾
                                   PCBsQueues[i-1].setQueue(nextQueue);//将取出的队列放回队列组
                                   showPCBQueues(PCBsQueues);
                               }
                           }

                            //nowTime++;
                            textArea.setText(String.valueOf(nowTime));//用于在时钟对应位置展示此时的nowTime,即当前时间
                            break;//跳出for循环
                        }
                    }
                }

                if(isStopScheduling) {
                	//nowTime=0;
                	textArea.setText(String.valueOf("0.0"));//用于在时钟对应位置展示此时的nowTime,即当前时间
                }
                initMemory();//进程执行结束,初始化内存
                showPCBQueues(PCBsQueues);
                //所有进程均执行完成,进程调度完
                JOptionPane.showMessageDialog(frame, "进程调度完成!");
                //frame.dispose();
            }
        }).start();

    }

三、运行界面

1、运行预览

在这里插入图片描述

2、主界面

以多级反馈队列算法为例,其他算法大致相同。
在这里插入图片描述

四、源代码下载

https://github.com/LZshangan/OSProcessSchduling
支持开源,希望能帮助有需要的人,欢迎下载,欢迎完善。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值