操作系统实验报告实验名称:I/O管理评分:班级:计科1602班学号:201610352姓名:王岩一.实验目的:⒈通过设计并运行一个简单的SPOOLing系统来模拟SPOOLing输入/出过程,以掌握这种有用的技术,从而熟悉基本的;⒉加深对输入输出管理的了解;二.实验要求:⒈要求将SPOOLing输入/出处理程序编成一个独立的进程模块并与其他请求输入/出的进程并发运行;⒉SPOOLing进程负责把从输入设备读入的信息送到外存输入井中,或把外存输入井中的信息送到打印机等输出设备上输出。其余进程只要求编写输入出部分程序。三.实验题目和内容:1.问题描述本系统利用内存来模拟SPOOLing输出过程。管理系统包括一个SPOOLing输出进程模块spoolout和一个SPOOLing输出请求服务程序spoolserver。Spoolserver负责接收并处理用户进程的输出请求;spoolout完成实际的输出。另外,系统中设计了3个请求SPOOLing输出的用户进程。它们共享用户进程模块userpro。2.数据结构⑴进程控制块PCB,内容含有:id进程标识数;status进程运行状态,可为“e”(执行)或“c”(完成);bufflag输出缓冲区空闲标志,FALSE为空闲;filec输出文件计数。本系统赋予spoolout进程和3个用户进程的标识数分别为0,1,2,3。程序启动后,在完成必要的初始化工作后便显示命令选择菜单,根据输入命令调用相应的功能模块。系统每完成一次请求即输出执行结果,直至键入“Quit”命令(命令码“4”)。系统退出运行为止。⑵输出请求块reqblock,内容含有:reqid请求进程标识数;size输出文件长度;addr输出文件在输出井中的首地址。⑶输出井,用数组well[]表示。⑷输出缓冲区,用二维数组userbuf[3][]表示。每个用户进程分别使用各自的输出缓冲区。此外,系统中还安排了下列管理数据(均属全程量):ebc空闲reqblock计数,初值为10;ebp当前空闲reqblock指针,初值为0;cbp当前非空reqblock指针,初值为0;wellsize输出井当前可用空间的大小;wellptr输出井环形指针,指初当前空区首地址;n用户的输出请求总数,用以控制系统的运行结束。⒊算法进程调度采用随机调度法。3个用户进程的调度概率各为30%,spoolout进程为10%。这由产生随机数来模拟。用户进程在各自的缓冲区中形成输出信息序列,而后调用服务程序spoolserver请求输出。Spoolserver接受输出请求,从相应输出缓冲区中取出信息序列送输出井,并构造一个reqblock,提交spoolout进程使用,然后返回用户进程继续执行。Spoolout进程执行时,根据取出的某reqblock的内容将输出井中的相应输出文件送实际输出设备,如打印机或CRT,随之释放相应井区。四.实验程序#includestdio.h#includecstring#includecstdlib#includectimestructinfo_PCB{longID;//进程标识longstatus;//状态longpo;//输出指针longhead;//信息块首地址longcount;//输出长度longwait[1000];//输出缓冲}PCB[4];structinfo_block{longID;//要求输出的进程longlen;//输出长度longhead;//输出首地址}block[128];structinfo_wall{longnum[10000];//输出内容longopen,closed;//队列指针}wall[3];longK[3],L1,L2[3];longn;voidinput(){//输入函数printf(inputthetimesofuser1`soutputfile:);scanf(%ld,&K[1]);printf(inputthetimesofuser2`soutputfile:);scanf(%ld,&K[2]);}voidinit(){//初始化函数L1=10;L2[1]=L2[2]=100;memset(PCB,0,sizeof(PCB));PCB[1].ID=1;PCB[2].ID=2;PCB[3].ID=3;PCB[3].status=2;memset(wall,0,sizeof(wall));n=0;}voidwork(){//模拟进程调度longr;longk;longa,b;longi,j;while(PCB[1].status!=3||PCB[2].status!=3||PCB[3].status!=3){r=rand()%100+1;//用随机数模拟进程执行概率if(r=45){k=1;}else{if(r=90)k=2;elsek=3;}if(PCB[k].status!=0)continue;switch(k){case1:case2://输入进程ka=rand()%10;++PCB[k].po;PCB[k].wait[PCB[k].po]=a;if(a==0){b=wall[k].closed+1;for(i=1;i=PCB[k].po;i++){wall[k].num[++wall[k].closed]=PCB[k].wait[i];}PCB[k].po=0;PCB[k].count++;if(PCB[k].count==K[k]){//进程执行完毕后应置成“结束状态”PCB[k].status=3;}if(PCB[3].status==2){//要求输出进程在输出信息到输出井并形成信息快后,应将spooling进程置成“可运行状态”PCB[3].status=0;}if(L2[k]==0&&PCB[k].status==0){//如果输出井满,将进程置为“不可运行状态1”PCB[k].status=1;}n++;block[n].ID=k;block[n].head=b;block[n].len=wall[k].closed-b+1;printf(Process%ldproducesablock%ld!\n,k,n);}break;case3://Spooling进程PCB[3].po++;a=PCB[3].po;printf(Outputblock%ld:(ID=%ld)\n,a,block[a].ID);for(i=1;i=block[a].len;i++){printf(%ld,wall[block[a].ID].num[i+block[a].head-1]);}printf(\n);if(PCB[3].po==n){PCB[3].status=2;//Spooling进程在输出井空时置成“不可运行状态2”if(PCB[1].status==3&&PCB[2].status==3){PCB[3].status=3;}}break;}}}intmain(){srand(time(NULL));input();init();work();return0;}五.实验结果首先进行输入产生结果如下图:六.实验总结通过本次实验,加深了对与设备管理的连接和认识,了解了各种数据结构在设备管理中的作用和操作系统进行设备管理的原理,而SPOOLing技术就是在内核外运行的系统I/O软件,采用预输入、缓输出和井管理技术,是多道程序设计系统中处理独占型设备的一种方法,创建守护进程和特殊目录解决独占型设备的空占问题。