1、 “操作系统课程设计”总结报告目录一、 进程控制1二、 请求分页存储器管理3三、 设备管理7四、 文件管理17五、 进程调度算法的实现25六、 课程总结28本学期开设了操作系统课程,主要学习了计算机操作系统方面的知识(进程控制、进程调度、请求分页存储管理、设备管理、文件管理),了解了操作系统的相关应用,并通过“操作系统课程设计”实现了一套模拟的单用户多任务操作系统,掌握了操作系统包括进程管理、存储管理、设备管理和文件管理四部分。更深刻地领会操作系统工作原理和操作系统实现方法,并提高程序设计能力。以下是课程设计五个设计内容的总结。一、 进程控制1.1目的通过简单的结构和控制方法,完成模拟进程结构
2、、进程状态和进程控制,掌握进程控制的实现。1.2完成的内容1、用PCB表示整个进程实体,利用随机数方法或键盘控制方法模拟进程执行中产生的事件操作控制进程管理内容。2、定义PCB:包括理论PCB中的基本内容,如内部ID、外部ID、进程状态、队列指针。由于无法实现真正的进程创建功能,在实验中只需建立PCB,用它代表完整的进程。3、定义进程状态转换方式:进程的状态转换是由进程内部操作或操作系统的控制引起,由于无法实现这些功能,采用随机数方法或键盘控制方法模拟,并实现对应的控制程序。随机方法指产生16的随机数,分别代表创建进程(c)、结束进程(e)、进程阻塞(b)、激活进程(w)、调度进程(p)、时间
3、片到(t)等事件;键盘模拟方法指定义6种按键代表以上6种事件。4、根据事件处理就绪队列、阻塞队列和当前执行进程的状态。每次事件处理后应形象地显示出当前系统中的执行进程是哪一个,就绪队列和阻塞队列分别包含哪些进程。1.3主要数据结构void create() /新建struct PCB *temp;char name10;printf(process name:);scanf(%s,name);temp=(struct PCB *)malloc(sizeof(struct PCB);strcpy(temp-name,name); /拷贝temp-next=NULL;add(ready,temp)
4、;if(running=NULL)running=removeFirst(ready);void interupt()/中断if(running!=NULL)add(ready,running);running=removeFirst(ready);void block()/阻塞 if(running!=NULL)add(blocked,running);running=removeFirst(ready);void wakeup()/唤醒if(blocked-next!=NULL) add(ready,removeFirst(blocked);if(running=NULL)running=
5、removeFirst(ready); void finished()/终止if(running!=NULL)free(running);running=removeFirst(ready);就绪1.4算法设计及流程图阻塞执行建立三个链表分别表示就绪队列、执行队列、阻塞队列;根据不同的命令对相应的队列进行增删改;1.5小结(如何实现的?可以以关键部分流程图、主要数据结构、程序整体框架等内容表示。)二、 请求分页存储器管理2.1目的通过在第1部分实验基础上实现进程的分页式内存分配和地址转换过程,完成请求分页式存储分配和地址转换过程,掌握页面置换算法:先进先出(FIFO)、最近最久未使用(LRU)
6、等算法。2.2完成的内容1、建立一个位示图,用来模拟内存的分配情况,位示图的位数与设定的物理块个数相同。程序启动时可利用一组随机0和1填充位示图,表示内存已被占用情况。2、创建进程时输入进程大小,并根据程序中设定的物理块大小为进程分配物理块,同时建立页表。3、输入当前执行进程所要访问的逻辑地址,并将其转换成相应的物理地址。4、进程退出时,根据其页表内容向位示图反向回填“1”。5、扩充页表,将其变成支持请求和置换功能的二维页表(增加存在位等)。创建进程时可装入固定的前三页(或键盘输入初始装入页数,不同进程的装入个数可以不同),其余页装入到置换空间内。6、分别采用FIFO和LRU置换算法对地址转换
7、过程中遇到的缺页现象进行页面置换,可将多次地址转换过程中所涉及到的页号视为进程的页面访问序列,从而计算置换次数和缺页率.2.3主要数据结构struct page_table_itemint pagenum;int blocknum;int exist; /存在位int modify; /修改位int swap_add;2.4算法设计及流程图void terminate()int i,j,p,q;if(running=NULL) printf(已结束所有进程!);if(running!=NULL)j=ceil(running-size,PAGE_SIZE);if(j3)for(i=0;ipage
8、table+i).blocknum/8;q=(*(running-pagetable+i).blocknum%8;/printf(%d,p);setbit(&bitmapp,q,0);for(i=3;ipagetable+i).blocknum/8;q=(*(running-pagetable+i).blocknum%8; / printf(%d %dn,p,q);/printf(%d,p);setbit(&changemapp,q,0);elsefor(i=0;ipagetable+i).blocknum/8;q=(*(running-pagetable+i).blocknum%8;setb
9、it(&bitmapp,q,0);free(running);if(ready!=NULL)running=removeFirst(ready);void translate()/逻辑地址转换成物理地址if(running=NULL)printf(没有执行进程);elseint logical;int pagenum,offset;int blocknum;printf(请输入逻辑地址:n);scanf(%d,&logical);pagenum=(int)(logical/PAGE_SIZE);offset=logical%PAGE_SIZE;blocknum=(running-pagetab
10、le+pagenum)-blocknum; /blocknum=*(running-pagetable+pagenum); printf(物理地址:%d,blocknum*PAGE_SIZE+offset);printf(n);/blockno=*(running-pagetable + pageno); void dispagetable()/显示执行进程页表int i;if(running=NULL)printf(没有执行进程); return;for(i=0;isize,BLOCK_SIZE);i+)printf( %d %d %d %d %d n,(*(running-pagetabl
11、e+i).pagenum,(*(running-pagetable+i).blocknum,(*(running-pagetable+i).exist,(*(running-pagetable+i).modify,(*(running-pagetable+i).swap_add);2.5小结三、 设备管理3.1目的通过在前面的实验基础上,完成设备管理功能的模拟,掌握包括通道和控制器的添加和删除,设备的添加、删除,设备的分配和回收 。3.2完成的内容1、设备管理子系统涉及到系统设备表(SDT)、通道控制表(CHCT)、控制器控制表(COCT)和设备控制表(DCT)来体现输入输出系统的四级结构和三
12、级控制。2、实现上述设备、控制器以及通道的层次关系,同时能够添加或删除新的设备、控制器或通道。3、通过键盘命令模拟进程执行过程中提出的设备分配或释放请求,并为此请求分配或释放设备。分配设备成功后可将进程状态调整为阻塞,释放设备后变为就绪状态。4、分配设备时应如果该设备已被其它进程占用,则设备分配失败,请求进程进入阻塞状态,同时等待该设备的释放。如果设备空闲,进程占用设备的同时还应提出申请控制器请求,直到与设备相关的通道都已申请成功为止。5、设备、控制器或通道的释放应引起对应节点的等待队列中的第一个阻塞进程被唤醒。如果被唤醒的进程还未完成申请操作,应继续执行上级节点的申请操作。3.3主要数据结构
13、struct Node *DCTs,*COCTs,*CHCTs;/添加头结点,设备,控制器,通道struct Node *addNode(char *name,struct Node *parent,struct Node *head)/在以head为头结点队列中添加名为name的节点struct Node *tmp=head;/查找最末位节点while(tmp-next!=NULL)tmp=tmp-next;tmp-next=(struct Node *)malloc(sizeof(struct Node);strcpy(tmp-next-name,name);tmp-next-next=N
14、ULL;tmp-next-parent=parent;tmp-next-process=NULL;tmp-next-ready=(struct PCB *)malloc(sizeof(struct PCB);tmp-next-ready-next=NULL;return tmp-next;3.4算法设计及流程图int get_child_count(struct Node *node,struct Node *childs_head)/获取一个节点的所有子节点int count=0;struct Node *tmp=childs_head-next;while(tmp!=NULL)if(tmp
15、-parent=node)count+;tmp=tmp-next;return count;struct Node *findByName(char *name,struct Node *head)struct Node *tmp=head-next;while(tmp!=NULL)if(strcmp(tmp-name,name)=0)/比较当前节点,相等就返回这个节点,否则查看下一个节点return tmp;tmp=tmp-next;printf(%cError:cant find %s!n,BEEP,name);/名为name的节点未找到return NULL;void removeNod
16、e(char *name,struct Node *head)struct Node *tmp1=head;struct Node *tmp2=head-next; while(tmp2!=NULL)/节点实际存在if(strcmp(tmp2-name,name)=0)/比较if(tmp2-process=NULL & tmp2-ready-next=NULL)tmp1-next=tmp2-next;free(tmp2);elseprintf(%cError:cant remove %s!n,BEEP,name);return;tmp1=tmp2;tmp2=tmp2-next;printf(%
17、cError:cant find %s!n,BEEP,name);/struct Node *addNode(char *name,struct Node *parent,struct Node *queue)/*void remove Node(char *name,struct Node*queue)*/void add_devices()/添加设备int i;char name10,parent10;while(1)printf(1:add devicen);/设备printf(2:add controllern);/控制器printf(3:add channeln);/通道printf
18、(0:returnn);/返回主程序scanf(%d,&i);/i变量读菜单if(i!=0)printf(name:);scanf(%s,name);if(i=1 | i=2)printf(parent name:);scanf(%s,parent);switch(i)case 1:addNode(name,findByName(parent,COCTs),DCTs);/所添加的设备名在name里,通过parent名在COCT队列中找到父节点,之后以这个节点,这个名称为参数在DCT队列中添加一个新结点break;case 2:addNode(name,findByName(parent,CHC
19、Ts),COCTs);break;case 3:addNode(name,NULL,CHCTs);/通道没有父节点break;case 0:return ;void remove_devices()int i;char name10;struct Node *tmp;while(1)printf(1:remove devicen);printf(2:remove controllern);printf(3:remove channeln);printf(0:returnn);scanf(%d,&i);if(i!=0)printf(name:);scanf(%s,name);switch(i)c
20、ase 1:removeNode(name,DCTs);break;case 2:tmp=findByName(name,COCTs);if(tmp=NULL)printf(%cError:cant find %s!n,BEEP,name);else if(get_child_count(tmp,DCTs)0) /子节点个数printf(%cError:cant remove %s!n,BEEP,name);elseremoveNode(name,COCTs);break;case 3:tmp=findByName(name,CHCTs);if(tmp=NULL)printf(%cError:
21、cant find %s!n,BEEP,name);else if(get_child_count(tmp,COCTs)0)printf(%cError:cant remove %s!n,BEEP,name);elseremoveNode(name,CHCTs);break;case 0:return;void allocate_channel(struct Node *node,struct PCB *p) if(p=NULL)return; if(node-process=NULL)node-process=p;block(blocked,p);else block(node-ready,
22、p);void allocate_controller(struct Node *node,struct PCB *p) if(p=NULL)return; if(node-process=NULL)node-process=p;allocate_channel(node-parent,p);else block(node-ready,p);void allocate_device(struct Node *node,struct PCB *p) if(p=NULL)return;if(node-process=NULL)node-process=p;allocate_controller(n
23、ode-parent,p);elseblock(node-ready,p);void allocate()char name10;struct Node *node; if(running=NULL)return;printf(device name:);scanf(%s,name);node=findByName(name,DCTs);if(node=NULL)printf(Cant find %s!n,name);return;allocate_device(node,running);void release_channel(struct Node *node,struct PCB *p
24、) if(node-process=p)node-process=NULL;allocate_channel(node,removeFirst(node-ready);add(ready,remove_process(blocked,p);if(running=NULL)running=removeFirst(ready);elseadd(ready,remove_process(node-ready,p);if(running=NULL)running=removeFirst(ready);void release_controller(struct Node *node,struct PC
25、B *p) if(node-process=p)node-process=NULL;allocate_controller(node,removeFirst(node-ready);release_channel(node-parent,p);elseadd(ready,remove_process(node-ready,p);if(running=NULL)running=removeFirst(ready);void release()char name10;struct Node *node;struct PCB *p;printf(device name:);scanf(%s,name
26、);node=findByName(name,DCTs);if(node=NULL | node-process=NULL)return;p=node-process;node-process=NULL;allocate_device(node,removeFirst(node-ready);release_controller(node-parent,p);void display_process_status(struct Node *node)/显示节点的占用进程以及等待进程信息struct PCB *p=node-ready-next;if(node-process!=NULL)pri
27、ntf(process-name);while(p!=NULL)printf(name);p=p-next;printf(n);void display_status()/显示设备状态struct Node *chct=CHCTs-next,*coct,*dct;while(chct!=NULL)printf(%s,chct-name);display_process_status(chct);coct=COCTs-next;while(coct!=NULL)if(coct-parent=chct)printf(t%s,coct-name);display_process_status(coc
28、t);dct=DCTs-next;while(dct!=NULL)if(dct-parent=coct)printf(tt%s,dct-name);display_process_status(dct);dct=dct-next;coct=coct-next;chct=chct-next;3.5小结四、 文件管理4.1目的通过利用磁盘文件,完成操作系统的文件管理功能,掌握包括目录结构的管理、外存空间的分配与释放以及空闲空间管理三部分 。4.2完成的内容1、通过初始化操作建立一个模拟外存空间的虚拟磁盘文件,在该文件中保存目录和文件内容。创建该文件时应创建初始的根目录内容、文件分配表。2、文件目录
29、项(可以采用FCB格式)应包括类型(目录 or文件)、创建日期、大小、第一个磁盘块块号。3、显示命令提示符“$”,并根据输入命令完成相应的文件操作:n MD(创建子目录):创建目录文件,并在父目录文件中增加目录项。n CD(切换工作目录):根据当前目录切换到指定目录。n RD(删除子目录):搜索所要删除的目录是否为空目录,若是则删除。n MK(创建空文件):创建指定大小的文件(如输入命令 “mk test 2000”,表示创建大小为2000字节的test文件),并在父目录中添加文件名称;还应对FAT表进行适当修改。n DEL(删除文件):如果所要删除的文件存在,则删除,同时修改父目录内容;还应
30、对FAT表进行适当修改。n DIR:列出当前目录的所有目录项。n FORMAT:根据进一步的虚拟磁盘文件名和块个数信息创建出虚拟磁盘文件。4.3主要数据结构struct FCBchar name8;int size;int first_block;char datetime15;char type;char current_directory256=;/当前目录char formated_file_name32;/虚拟磁盘文件名int current_directory_block_no=0;/当前目录块号4.4算法设计及流程图void md(char *name)if(!is_valid_n
31、ame(name)return;struct FCB *directory_content=(struct FCB *)malloc(BLOCK_SIZE);read_block(current_directory_block_no,(char *)directory_content);if(get_directory_item(directory_content,1,name)!=NULL | get_directory_item(directory_content,2,name)!=NULL)alert(所要创建的目录名已被占用);free(directory_content);retur
32、n;int block_no=get_empty_block_number(0);if(block_no0)alert(虚拟磁盘空间已耗尽);free(directory_content);return;struct FCB *tmp=directory_content;for(int i=0;itype=0)char datetime15;get_datetime(datetime);strcpy(tmp-datetime,datetime);tmp-size=BLOCK_SIZE;tmp-type=(char)2;tmp-first_block=block_no;strcpy(tmp-na
33、me,name);write_block(current_directory_block_no,(char *)directory_content);set_fat_item(block_no,LAST_BLOCK);free(directory_content);write_directory_content(block_no,current_directory_block_no,datetime);return;void dir()struct FCB *directory_content=(struct FCB *)malloc(BLOCK_SIZE);read_block(curren
34、t_directory_block_no,(char *)directory_content);struct FCB *tmp=directory_content;for(int i=0;itype=1 | tmp-type=2)int type=tmp-type;if(tmp-first_block=0)printf(%dt,tmp-first_block);elseprintf(t);*(tmp-datetime+15)=0;printf(%st,tmp-datetime);if(tmp-type=2)printf(t);elseprintf(%dt,tmp-size);printf(%s
35、n,tmp-name);free(directory_content);void cd(char *name)if(name=NULL)printf(%sn,strlen(current_directory)=0?:current_directory);else if(strcmp(name,.)=0)return;else if(strcmp(name,)=0)current_directory_block_no=0;strcpy(current_directory,);elsestruct FCB *directory_content=(struct FCB *)malloc(BLOCK_
36、SIZE);read_block(current_directory_block_no,(char *)directory_content);struct FCB *tmp=get_directory_item(directory_content,2,name);if(tmp=NULL)alert(没有找到子目录项!);else if(strcmp(tmp-name,.)=0)char *sub_name=strcat(current_directory,);current_directory_block_no=tmp-first_block;substr(current_directory,
37、current_directory,0,sub_name-current_directory);/testsub-tetselsecurrent_directory_block_no=tmp-first_block;strcat(current_directory,);strcat(current_directory,name);free(directory_content);void rd(char *name)/rd testvoid mk(char *name,int size,char *content)if(!is_valid_name(name)return;struct FCB
38、*directory_content=(struct FCB *)malloc(BLOCK_SIZE);read_block(current_directory_block_no,(char *)directory_content);if(get_directory_item(directory_content,1,name)!=NULL | get_directory_item(directory_content,2,name)!=NULL)alert(所要创建的目录名已被占用);free(directory_content);return;int block_no=get_empty_bl
39、ock_number(0);if(block_no0)alert(虚拟磁盘空间已耗尽);free(directory_content);return;struct FCB *tmp=directory_content;for(int i=0;itype=0)char datetime15;get_datetime(datetime);strcpy(tmp-name,name);strcpy(tmp-datetime,datetime);tmp-size=size;tmp-type=(char)1;tmp-first_block=block_no;if(size0)tmp-first_block=block_no;int block_count=(int)ceil(size/(double)BLOCK_SIZE);int *block_numbers=(int *)malloc(sizeof(int)*block_count);*block_numbers=block_no;for(int j=1;jblock_count;j+)*(block_numbers+j)=get_empty_block_number(*(block_numbers+j-1)+1);/ff