实验目的:利用简单的结构和控制方法模拟进程结构、进程状态转换和进程控制。
方法:用PCB表示整个进程实体,利用键盘交互式命令控制方法模拟进程执行中产生的事件。
实现功能:
OS 进程控制
1、自动调度(省略 P 操作)
2、为进程分配空间(OS起始地址为100 原有空间大小为440k)
3、结束进程后回收空间
4、重名进程判断
5、将操作过程存入文件RUNLOG.txt中
创建进程(c)、结束进程(e)、进程阻塞(b)、激活进程(w)、调度进程(p)、时间片到(t)等事件;键盘模拟方法指定义6种按键代表以上6种事件。
主要思想:
通过链表建立起空白PCB和空闲的内存块(memory)。
实现以上所有功能都有一个共同的特点,都是不断的将结点从链表的尾部摘下然后利用尾插法插入到另一个链表上去。
数据结构:
.
实现过程:#include<stdio.h> #include<stdlib.h> #include<malloc.h> #include<string.h> FILE *out=fopen("RUNLOG.txt","w"); struct linklist { char name[255]; int startad,process_size; linklist *next; }; struct memory { int size,saddress; memory *next; }; memory *OS; linklist *head_PCB,*rear_PCB; linklist *head_READY,*rear_READY; linklist *head_EXCUTE,*rear_EXCUTE; linklist *head_BLOCK,*rear_BLOCK; void init(int n) //建立空白PCB { head_PCB=rear_PCB=NULL; head_READY=rear_READY=NULL; head_EXCUTE=rear_EXCUTE=NULL; head_BLOCK=rear_BLOCK=NULL; while(n--) { if(head_PCB==NULL) { rear_PCB=head_PCB=(linklist*)malloc(sizeof(linklist)); } else { rear_PCB->next=(linklist*)malloc(sizeof(linklist)); rear_PCB=rear_PCB->next; } rear_PCB->next=NULL; } OS=(memory*)malloc(sizeof(memory)); OS->next=NULL; OS->saddress=100; OS->size=440; } linklist* delete_linklist(linklist *&head,linklist *&rear)//摘下结点 { linklist *p; p=head; if(p==NULL) { rear=NULL; return NULL; } head=head->next; p->next=NULL; return p; } void insert_linklist(linklist *&head,linklist *&rear,linklist *p)//插入 { if(head==NULL) { head=rear=p; } else { rear->next=p; rear=p; } } void show() //显示当前进程 { linklist *r=head_READY,*e=head_EXCUTE,*b=head_BLOCK; printf("Ready process: "); while(r) { printf("%s\t",r->name); r=r->next; } printf("\nEXCUTE process: "); while(e) { printf("%s\t",e->name); e=e->next; } printf("\nBLOCK process: "); while(b) { printf("%s\t",b->name); b=b->next; } printf("\nOS empty space :\n"); memory *s; s=OS; while(s) { printf("Start address :%d Size :%d\n",s->saddress,s->size); s=s->next; } if(OS==NULL) { printf("No left memory!"); } printf("\n"); } void menu() { printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n"); printf("┃ C : Create a process.You must input the name of process. ┃ \n"); printf("┃ E : End the process. ┃\n"); printf("┃ B : Block the process.You must input the name of process. ┃ \n"); printf("┃ W : Wakeup the process.You must input the name of process. ┃\n"); printf("┃ T : Time Over. ┃ \n"); printf("┃ S : Show All the process name. ┃\n"); printf("┃ H : Help. ┃\n"); printf("┃ # : Exit. ┃\n"); printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n"); } void share(int &saddr,int &size) //为进程分配空间 { memory *p,*k,*best_fit,*m; int min_place=10000000; best_fit=NULL; k=NULL; p=OS; while(p!=NULL) { if(p->size>=size && p->size-size<min_place) /*在OS空闲空间中找出最佳分配的结点*/ { best_fit=p; min_place=p->size-size; m=k; /*m保存了最佳分配的结点的前趋*/ } k=p; /*k保存p的前趋*/ p=p->next; } saddr=best_fit->saddress; best_fit->size-=size; best_fit->saddress+=size; if(best_fit->size<4) /*如果剩余空间小于4k则释放结点*/ { if(m==NULL) { memory *s; s=OS; OS=OS->next; size+=best_fit->size; free(s); } else { m->next=best_fit->next; size+=best_fit->size; free(best_fit); } } } void recycle(int &addr,int &size)//回收 { memory *p,*k; p=OS; k=NULL; if(p==NULL) //OS原内存无空闲空间 { OS=(memory*)malloc(sizeof(memory)); OS->saddress=addr; OS->size=size; OS->next=NULL; } else { while(p!=NULL) { if(p->saddress+p->size<=addr) { k=p; } else break; p=p->next; } if(k==NULL) { if(addr+size==p->saddress)//如果可以和下一个结点合并 { p->saddress=addr; p->size+=size; return ; } else { memory *s; s=(memory *)malloc(sizeof(memory)); s->saddress=addr; s->size=size; s->next=p; OS=s; } } else { if(k->saddress+k->size==addr) /*与上一结点合并*/ { k->size+=size; if(k->next!=NULL && k->saddress+k->size==k->next->saddress) /*查看是否能与下一结点合并*/ { k->size+=k->next->size; memory *s; s=k->next; k->next=s->next; free(s); } } else if(k->next!=NULL && addr+size==k->next->saddress) /*上占下空*/ { k->next->saddress=addr; k->next->size+=size; } else /*上占下占*/ { memory *s; s=(memory *)malloc(sizeof(memory)); s->saddress=addr; s->size=size; s->next=k->next; k->next=s; } } } } int os(int x) { memory *p=OS; while(p!=NULL) { if(p->size>=x) return 1; p=p->next; } return 0; } int judgename(char *s) //判断是否有重名进程 { linklist *r,*e,*b; r=head_READY; e=head_EXCUTE; b=head_BLOCK; while(r!=NULL) { if(strcmp(r->name,s)==0) break; r=r->next; } if(r==NULL) { while(e!=NULL) { if(strcmp(e->name,s)==0) break; e=e->next; } if(e==NULL) { while(b!=NULL) { if(strcmp(b->name,s)==0) break; b=b->next; } if(b==NULL) return 1; //没有重名进程 return 0; } else return 0; } else { return 0;//有重名进程 } } void cometrue() //功能实现 { char ch; char a[255],b[255]; while(1) { scanf("%c",&ch); if(ch!='s'&&ch!='S'&&ch!='#'&&ch!='\n') fprintf(out,"%c\n",ch); if(ch=='c'||ch=='C') //创建进程 { if(head_PCB==NULL) { printf("No PCB!"); fprintf(out,"No PCB!\n"); } else { linklist *p; p=delete_linklist(head_PCB,rear_PCB); printf("Please input the process's name: \n-"); scanf("%s",p->name); if(judgename(p->name)) { printf("Please input the place this process need: \n-"); scanf("%d",&p->process_size); if(os(p->process_size)) { share(p->startad,p->process_size); insert_linklist(head_READY,rear_READY,p); itoa(p->process_size,a,10); itoa(p->startad,b,10); printf("Create %s process success! Start address is %d. Size is %d.\n",p->name,p->startad,p->process_size); fprintf(out,"Create %s process success! Start address is %s. Size is %s.\n",p->name,b,a); if(head_EXCUTE==NULL) insert_linklist(head_EXCUTE,rear_EXCUTE,delete_linklist(head_READY,rear_READY)); } else { printf("OS memory limit!\n"); fprintf(out,"OS memory limit!\n"); } } else { while(judgename(p->name)==0) { printf("Error: Can not create process,the process exist.\n"); fprintf(out,"Error: Can not create process,the process exist.\n"); printf("Here is all exist process:\n"); show(); printf("Please input another name: \n-"); scanf("%s",p->name); } printf("Please input the place this process need: \n-"); scanf("%d",&p->process_size); if(os(p->process_size)) { share(p->startad,p->process_size); insert_linklist(head_READY,rear_READY,p); itoa(p->process_size,a,10); itoa(p->startad,b,10); printf("Create %s process success! Start address is %d. Size is %d.\n",p->name,p->startad,p->process_size); fprintf(out,"Create %s process success! Start address is %s. Size is %s.\n",p->name,b,a); if(head_EXCUTE==NULL) insert_linklist(head_EXCUTE,rear_EXCUTE,delete_linklist(head_READY,rear_READY)); } else { printf("OS memory limit!\n"); fprintf(out,"OS memory limit!\n"); } } } printf("In put your command \n>"); } else if(ch=='b'||ch=='B') // 阻塞 { if(head_EXCUTE==NULL) { printf("Error: No excute process!\n"); fprintf(out,"Error: No excute process!\n"); } else { insert_linklist(head_BLOCK,rear_BLOCK,delete_linklist(head_EXCUTE,rear_EXCUTE)); if(head_READY!=NULL) insert_linklist(head_EXCUTE,rear_EXCUTE,delete_linklist(head_READY,rear_READY)); } printf("In put your command \n>"); } else if(ch=='e'||ch=='E') //结束进程 { if(head_EXCUTE==NULL) { printf("Error: No excute process!\n"); fprintf(out,"Error: No excute process!\n"); } else { linklist *p; p=delete_linklist(head_EXCUTE,rear_EXCUTE); recycle(p->startad,p->process_size); printf("End %s process success!\n",p->name); fprintf(out,"End %s process success!\n",p->name); if(head_READY!=NULL) insert_linklist(head_EXCUTE,rear_EXCUTE,delete_linklist(head_READY,rear_READY)); } printf("In put your command \n>"); } else if(ch=='w'||ch=='W') //唤醒一个进程 { if(head_BLOCK==NULL) { printf("Error: No block process!\n"); fprintf(out,"Error: No block process!\n"); } else { insert_linklist(head_READY,rear_READY,delete_linklist(head_BLOCK,rear_BLOCK)); if(head_EXCUTE==NULL) insert_linklist(head_EXCUTE,rear_EXCUTE,delete_linklist(head_READY,rear_READY)); } printf("In put your command \n>"); } else if(ch=='t'||ch=='T') //时间片到 { if(head_EXCUTE!=NULL) { insert_linklist(head_READY,rear_READY,delete_linklist(head_EXCUTE,rear_EXCUTE)); insert_linklist(head_EXCUTE,rear_EXCUTE,delete_linklist(head_READY,rear_READY)); } else { printf("Error: No excute process!\n"); fprintf(out,"Error: No excute process!\n"); } printf("In put your command \n>"); } else if(ch=='s'||ch=='S') //显示所有进程 { show(); printf("In put your command \n>"); } else if(ch=='h'||ch=='H') //帮助、显示菜单 { menu(); printf("In put your command \n>"); } else if(ch=='#') //退出 { return ; } else { printf("Bad command!\n>"); fprintf(out,"Bad command!\n"); } getchar(); //解决有时不识别scanf的问题 } } void main() { init(10); menu(); printf("In put your command \n>"); cometrue(); fclose(out); }