www.pudn.com > os5.rar > os5.c


#include 
#include 
#define NULL 0 
#define getjcb(type) (type*)malloc(sizeof(type)) 
#define getsub(type)  (type*)malloc(sizeof(type)) 
 
int num,num2;  //要调度的作业数和要回收的区域数 
int m=0;     //已分配作业数 
int flag;     //分配成功标志 
int isup,isdown;   //回收区域存在上邻和下邻的标志 
int is=0; 
 
struct jcb{ 
		char name[10]; 
		char state; 
		int ntime; //所需时间 
	    int size;  //所需空间大小 
        int addr;  //所分配分区的首地址 
		struct jcb *link; 
	} *ready =NULL, *p,*q,*as=NULL;//作业队列ready,已分配作业队列as 
		typedef struct jcb JCB; 
struct subarea{         //分区块 
	    char name[10]; 
	    int addr;    //分区首地址 
		int size;    //分区大小 
		char state; 
		struct subarea *link; 
  } *sub=NULL,*r,*s,*cur; //空闲分区队列sub,当前分区指针cur 
        typedef struct subarea SUB; 
 
 
void sort() /* 建立对作业按到达时间进行排列的函数,直接插在队列之尾*/ 
{ 
 JCB *first; 
 if(ready==NULL)  ready=p; 
 else{ 
   first=ready; 
   while(first->link!=NULL) 
       first=first->link; 
   first->link=p; 
   p->link=NULL; 
  } 
} 
 
void sort3()      /*建立对已分配作业队列的排列函数,直接插在队列之尾*/ 
{ 
 JCB *fir; 
 if(as==NULL) as=q; 
 else{ 
   fir=as; 
   while(fir->link!=NULL) 
     fir=fir->link; 
   fir->link=q; 
   q->link=NULL; 
  } 
  m++; 
} 
 
void input() /* 建立作业控制块函数*/ 
{ 
 int i; 
 printf("\n请输入要调度的总作业数:"); 
 scanf("%d",&num); 
 for(i=0;iname); 
   printf("\n输入作业的大小:"); 
   scanf("%d",&p->size); 
   printf("\n输入作业所需运行时间:"); 
   scanf("%d",&p->ntime); 
   p->state='w'; 
   p->link=NULL; 
   sort(); /* 调用sort函数*/ 
  } 
 printf("\n 按任一键继续......\n"); 
 getch(); 
} 
 
 
 
 
 
void input2()     /*建立要回收区域的函数*/ 
{ 
 JCB *k; 
 int has; 
 q=getjcb(JCB); 
 printf("\n输入区域名(作业名):"); 
 scanf("%s",&q->name); 
 p=as; 
 while(p!=NULL) 
  {if(strcmp(p->name,q->name)==0)  /*在已分配作业队列中寻找*/ 
       { 
        q->addr=p->addr; 
        q->size=p->size; 
        has=1;    /*输入作业名存在标志位*/ 
        if(p==as)  as=p->link;    /*在已分配作业队列中删除该作业*/ 
        else 
          {k=as; 
	       while(k->link!=p)  k=k->link; 
	       k->link=k->link->link;      /*删除*/ 
	      } 
	    printf("输出该作业首地址:%d\n",q->addr); 
        printf("输出该作业大小:%d\n\n",q->size); 
        q->link=NULL; 
        break; 
       } 
   else 
       {p=p->link; has=0;}   /*输入作业名不存在标志*/ 
  } 
 if(has==0) 
  {printf("\n输入作业名错误!请重新输入!\n"); 
   input2(); 
  }   
} 
 
 
 
void print() 
{printf("\n\n\n\n"); 
 printf("\t\t**************************************\n"); 
 printf("\t\t\t三.存储管理实验演示\n"); 
 printf("\t\t**************************************\n\n\n"); 
 printf("\t\t\t\t蓝小花\n"); 
 printf("\t\t\t\t计算机学院\n"); 
 printf("\t\t\t\t软件4班\n"); 
 printf("\t\t\t\t3204007102\n"); 
 printf("\t\t\t\t2006年12月\n"); 
 printf("\n\n\n"); 
 printf("\t\t\t按任意键进入演示"); 
 getch(); 
 system("cls"); 
} 
 
 
 
void init_sub()       /*初始化空闲分区表*/ 
{ 
 r=getsub(SUB); 
 strcpy(r->name,"one"); r->addr=5; r->size=10; r->state='n'; 
 sub=r; 
 s=getsub(SUB); 
 strcpy(s->name,"two"); s->addr=20; s->size=120; s->state='n'; 
 sub->link=s;r=s; 
 s=getsub(SUB); 
 strcpy(s->name,"three"); s->addr=160; s->size=40; s->state='n';  
 r->link=s;r=s; 
 s=getsub(SUB); 
 strcpy(s->name,"four"); s->addr=220; s->size=10; s->state='n';  
 r->link=s;r=s; 
 s=getsub(SUB); 
 strcpy(s->name,"five"); s->addr=250; s->size=20; s->state='n';  
 r->link=s;r=s; 
 s=getsub(SUB); 
 strcpy(s->name,"six"); s->addr=300; s->size=80; s->state='n';  
 r->link=s;r=s; 
 s=getsub(SUB); 
 strcpy(s->name,"seven"); s->addr=400; s->size=60; s->state='n';  
 r->link=s;r=s; 
 s=getsub(SUB); 
 strcpy(s->name,"eight"); s->addr=480; s->size=300; s->state='n';  
 r->link=s;r=s; 
 s=getsub(SUB); 
 strcpy(s->name,"nine"); s->addr=850; s->size=150; s->state='n';  
 r->link=s;r=s; 
 s=getsub(SUB); 
 strcpy(s->name,"ten"); s->addr=1200; s->size=60; s->state='n';  
 r->link=s; 
} 
//-------------------------------------------------------------------------- 
void disp()    /*空闲分区表的显示函数*/ 
{ 
 printf("\n\n"); 
 printf("\t\t 分区          首地址           长度          状态 \n"); 
 r=sub; 
 while(r!=NULL) 
   { 
    printf("\t\t %s\t\t%d\t\t%d\t\t%c\n",r->name,r->addr,r->size,r->state); 
    r=r->link; 
   } 
 printf("\n"); 
} 
 
//-------------------------------------------------------------------------- 
void disp2()   /*显示已分配内存的作业表函数*/ 
{ 
 printf("\n\n"); 
 printf("\t\t 作业名         首地址          长度          状态 \n"); 
 p=as; 
 while(p!=NULL) 
   { 
    printf("\t\t %s\t\t%d\t\t%d\t\t%c\n",p->name,p->addr,p->size,p->state); 
    p=p->link; 
   } 
 printf("\n\n"); 
} 
 
 
//-------------------------------------------------------------------------- 
void assign2(JCB *pr) /*首次适应作业分区*/ 
{ 
 SUB *k; 
 r=sub;   /*从空闲表头开始寻找*/ 
 while(r!=NULL) 
  { 
   if(((r->size)>(pr->size))&&(r->state=='n'))   /*有空闲分区大于作业大小的情况*/ 
	  { 
	   pr->addr=r->addr; 
	   r->size-=pr->size; 
	   r->addr+=pr->size; 
	   flag=1;       /*分配成功标志位置1*/ 
	   q=pr; 
	   q->state='r'; 
	   sort3();     /*插入已分配作业队列*/ 
	   printf("作业%s的分区为[%s],首地址为%d.\n",p->name,r->name,pr->addr); 
	   break; 
	  } 
   else if(((r->size)==(pr->size))&&(r->state=='n'))    /*有空闲分区等于作业大小的情况*/ 
	  { 
	   pr->addr=r->addr; 
	   flag=1;    /*分配成功标志位置1*/ 
	   q=pr; 
	   sort3();	    /*插入已分配作业队列*/ 
	   s=sub;       /*空闲分区已完成分配,应删除*/ 
	   while(s->link!=r)  s=s->link; 
	   s->link=s->link->link;	 /*删除空闲分区*/ 
	   printf("作业%s的分区为[%s],首地址为%d.\n",p->name,r->name,pr->addr); 
	   break; 
	 } 
   else 
         {r=r->link;  flag=0;} 
} 
 if(flag==0)           /*作业过大的情况*/ 
 { 
  printf("作业%s长度过大,内存不足,分区分配出错!\n",p->name); 
  is=1; 
 } 
} 
 
//-------------------------------------------------------------------------- 
void reclaim2(JCB *pr)       /*首次适应与循环首次适应区域回收*/ 
{ 
 SUB *k; 
 r=sub; 
 while(r!=NULL) 
 { 
  if(r->addr==((pr->addr)+(pr->size)))     /*回收区域有下邻*/ 
    { 
	  pr->size+=r->size; 
	  s=sub; 
	  isdown=1;     /*下邻标志位置1*/ 
	  while(s!=NULL) 
	  { 
	   if(((s->addr)+(s->size))==(pr->addr))   /*有下邻又有上邻*/ 
	    { 
	     s->size+=pr->size; 
	     k=sub; 
	     while(k->link!=r)  k=k->link; 
	     k->link=k->link->link; 
	     isup=1;      /*上邻标志位置1*/ 
	     break; 
	    } 
	   else 
	    {s=s->link; isup=0;}    /*上邻标志位置0*/   
	  } 
 	  if(isup==0)               /*有下邻无上邻*/ 
	   {  
	     r->addr=pr->addr; 
	     r->size=pr->size; 
	   } 
	 break;	    
    } 
 else  
   {r=r->link; isdown=0;}     /*下邻标志位置0*/ 
 }   
 if(isdown==0)              /*区域无下邻*/ 
    {  
      s=sub; 
      while(s!=NULL)  
	  { 
	   if(((s->addr)+(s->size))==(pr->addr))   /*无下邻但有上邻*/ 
	     { 
	      s->size+=pr->size;  
	      isup=1;        /*上邻标志位置1*/ 
	      break; 
	     } 
	   else  
	     { s=s->link; isup=0;}     /*上邻标志位置0*/ 
	  } 
	  if(isup==0)           /*无下邻且无上邻*/ 
	       {  
	         k=getsub(SUB);   /*重新生成一个新的分区结点*/ 
	         strcpy(k->name,pr->name); 
	         k->addr=pr->addr; 
	         k->size=pr->size; 
	         k->state='n'; 
	         r=sub; 
	         while(r!=NULL) 
	         { 
	          if((r->addr)>(k->addr))   /*按分区首地址排列,回收区域插在合适的位置*/ 
	            { 
	              if(r==sub)       /*第一个空闲分区首址大于回收区域的情况*/ 
	                  { k->link=r; sub->link=k; } 
	              else 
	                 { 
	                  s=sub; 
	                  while(s->link!=r)  s=s->link;     
	                  k->link=r; 
	                  s->link=k; 
	                 } 
	              break; 
	            } 
	          else r=r->link; 
	         } 
	        if(r==NULL)     /*所有空闲分区的首址都大于回收区域首址的情况*/ 
	           { 
	             s=sub; 
	             while(s->link!=NULL)  s=s->link; 
	             s->link=k; 
	             k->link=NULL; 
	           } 
	       }     
    } 
 printf("\n区域%s己回收.",pr->name); 
} 
 
menu() 
{ 
  printf("\n\n\n\t\t**************************************\n"); 
 printf("\t\t\t存储管理实验演示\n"); 
 printf("\t\t**************************************\n\n\n"); 
 printf("\t\t\t 1. 显示空闲分区                  \n"); 
 printf("\t\t\t 2. 分配和回收作业                    \n"); 
 printf("\t\t\t 0. 退出                    \n"); 
 printf("\t\t\t请选择你要的操作:"); 
 switch(getchar()) 
{ 
    case '1': 
       system("cls"); 
        disp(); 
        getch(); 
        system("cls"); 
         menu(); 
        break; 
 case '2': 
            system("cls"); 
            printf("\n首次适应算法"); 
            input(); 
            printf("\n"); 
            while(num!=0) 
              { 
                p=ready; 
                ready=p->link; 
                p->link=NULL; 
                assign2(p); 
                num--; 
              } 
            printf("\n显示回收后的空闲分区表和已分配作业表..."); 
            getch(); 
            printf("\n\t\t              完成分配后的空闲分区表             \n"); 
            disp(); 
            printf("\n\t\t                  已分配作业表                   \n"); 
            disp2(); 
            if(is==0) 
               printf("\n 全部作业已经被分配内存."); 
            else printf("\n 作业没有全部被分配内存.\n"); 
 
            printf("\n\n按任意键进行区域回收."); 
            printf("\n"); 
 
            while(as!=NULL) 
              {getch(); 
               input2(); 
               printf("按任意键继续..."); 
               getch(); 
               printf("\n"); 
               reclaim2(q); 
               printf("\n显示回收后的空闲分区表和已分配作业表..."); 
               getch(); 
               printf("\n\t\t              回收后的空闲分区表             \n"); 
               disp(); 
               printf("\n\t\t                已分配作业表                 \n"); 
               disp2(); 
               printf("\n继续回收...(Enter)"); 
              } 
            printf("\n所有已分配作业已完成!"); 
            printf("\nPress any key to return..."); 
            getch(); 
            system("cls"); 
            menu(); 
            break; 
 
    case '0': 
           system("cls"); 
           break; 
            
    default: 
           system("cls"); 
           menu(); 
            
} 
} 
 
 
 
 
void main()     /*主函数*/ 
{ 
 init_sub(); 
 print(); 
 menu(); 
}