格式说明:排版时注意按此模板的字体,字号和行距。

报告提交和打印输出时请去掉此框。


实验三、进程模拟调度实验

一、        实验目的

用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解。



二、        实验内容和要求

     设计一个有 N个进程并发执行的进程调度模拟程序。

进程调度算法:采用最高优先级优先的调度算法(即把处理机分配给优先级最高的进程)和先来先服务(若优先级相同)算法。

(1).  每个进程有一个进程控制块(PCB)表示。进程控制块包含如下信息:进程名、优先级、到达时间、需要运行时间、已用CPU时间、进程状态等等。

(2).  进程的优先级及需要的运行时间可以事先人为地指定,进程的运行时间以时间片为单位进行计算。

(3).  每个进程的状态可以是就绪 r(ready)、运行R(Running)、或完成F(Finished)三种状态之一。

(4).  就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。

(5).  如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待调度。

(6).  每进行一次调度程序都打印一次运行进程、就绪队列中各个进程的 PCB,以便进行检查。   

(7).  重复以上过程,直到所要进程都完成为止。

 

 

三、        实验方法、步骤及结果测试


  1. 源程序代码:
#include<stdio.h> 
#define time int
#define max 10
typedef struct queue{  
	char name; 
	int number; 
 int intime; 
	int needtime;
 int runningtime;  
	int priority;
	char state;
}PCB; 
int n;
int ptime=1;
PCB pcb[max];
void addprocess(int n){
	int i;
	for(i=0;i<n;i++){
     printf("\n请输入进程名:");
	    scanf("%s", &pcb[i].name);
    	printf("\n请输入进程编号:");
    	scanf("%d", &pcb[i].number);
    	printf("\n请输入进程的优先级:");
    	scanf("%d", &pcb[i].priority);
    	printf("\n请输入进程的所需时间:");
    	scanf("%d", &pcb[i].needtime);
    	pcb[i].intime=i;
	    pcb[i].state='W';//将进程的状态初始化为等待态
	    pcb[i].runningtime=0;
	}
}
void sort(){
	int i,j;
	PCB temp;
	//通过排序将优先级最高的进程排到最前面
	for (i=0;i<n-1;i++)  
	{    
     for (j=n-2;j>=i;j--)   
	   {     
       if (pcb[j+1].priority>pcb[j].priority)    
	   {
         temp=pcb[j];      
         pcb[j]=pcb[j+1];     
         pcb[j+1]=temp;    
	   }   
	 }  
  }
	if (pcb[0].state!='F')  
  {    
    pcb[0].state='R';                //将优先级最高的状态置为运行  
  } 
}
void Print(){
  int i;     
  sort();  
  printf("\n  进程名    进程编号    优先级   到达时间  需要时间  已用时间  进程状态 \n");   
  for (i=0;i<n;i++)    
  {  printf("%8s%9d%10d%10d%10d%10d%10c\n",&pcb[i].name,pcb[i].number,pcb[i].priority,pcb[i].intime,pcb[i].needtime,pcb[i].runningtime,pcb[i].state);  
  } 
}

void attemper()                           //调度  
{           
  do{      
      if ((pcb[0].needtime-pcb[0].runningtime)>ptime)     
	    {           
        pcb[0].runningtime=pcb[0].runningtime+ptime;   //已用时间加时间片         
        pcb[0].priority--;            //优先级减一         
        pcb[0].state='W';     
	     }        
      else     
	    {       
        pcb[0].runningtime=pcb[0].needtime;//已用时间等于需要时间         
        pcb[0].priority=-1000;         //优先级置为零          
        pcb[0].state='F';             //完成进程,将状态置为完成     
	     }         
      Print();     
  }while(pcb[0].state!='F'); 
}
 


main(){ 
     n=0;
	 printf("请输入进程数:");
	 scanf("%d", &n);
   addprocess(n);
	 Print();
	 attemper(); 
      
}

 2.      主要程序段及其解释:

实现主要功能的程序段,重要的是程序的注释解释。

(1).定义结构体pcb:

typedef struct queue{  
	char name; 
	int number; 
    int intime; 
	int needtime;
    int runningtime;  
	int priority;
	char state;
}PCB;

(2).对进程按钮优先级进行排序:

void sort(){
	int i,j;
	PCB temp;
	//通过排序将优先级最高的进程排到最前面
	for (i=0;i<n-1;i++)  
	{    
     for (j=n-2;j>=i;j--)   
	 {     
       if (pcb[j+1].priority>pcb[j].priority)    
	   {
         temp=pcb[j];      
         pcb[j]=pcb[j+1];     
         pcb[j+1]=temp;    
	   }   
	 }  
  }
	if (pcb[0].state!='F')  
  {    
    pcb[0].state='R';                //将优先级最高的状态置为运行  
  } 
}

(3).进程调度的算法:

void attemper()                           //调度  
{           
  do{      
      if ((pcb[0].needtime-pcb[0].runningtime)>ptime)     
	  {           
        pcb[0].runningtime=pcb[0].runningtime+ptime;       //已用时间加时间片         
        pcb[0].priority--;            //优先级减一         
        pcb[0].state='W';     
	  }        
      else     
	  {       
        pcb[0].runningtime=pcb[0].needtime;//已用时间等于需要时间         
        pcb[0].priority=-1000;         //优先级置为零          
        pcb[0].state='F';             //完成进程,将状态置为完成     
	  }         
      Print();     
  }while(pcb[0].state!='F'); 
}

  3.      运行结果及分析

一般必须配运行结果截图,结果是否符合预期及其分析。   

  1. 进程调度 Python仿真 进程调度算法模拟实验_进程调度 Python仿真

  2.    图1:输入的进程的效果
  3. 进程调度 Python仿真 进程调度算法模拟实验_进程调度_02

  4.  2:进程调度的结果

  5. 进程调度 Python仿真 进程调度算法模拟实验_进程调度 Python仿真_03

  6. 3:进程调度的结果

  7. 进程调度 Python仿真 进程调度算法模拟实验_进程调度_04

  8. 4:进程调度的结果
  9. 进程调度 Python仿真 进程调度算法模拟实验_进程调度 Python仿真_05

  10. 5:进程调度的结果

  11. 进程调度 Python仿真 进程调度算法模拟实验_进程调度_06

 图6:进程调度的结果

四、        实验总结

       一开始用链式存储结果来构造对列,但是由于链式存储比较复杂,所以才用了顺序存储。顺序存储虽然比较简单,但是对进程的数有很大的限制,而且容易造成内存的浪费。所以还是链式存储比较好,还是要加强对链式存储的学习。