广西师范大学计算机科学与信息工程学院操作系统实验书
操作系统课程实验
年级 2012 级 专业 计算机科学与技术(应用型) 姓名 学号
指导教师 黄 玲 日期 2013年12月26日 1
广西师范大学计算机科学与信息工程学院操作系统实验书
实验七、设备管理实验
一、 关键问题
1、实验目的
观察Linux下U盘的访问;理解设备虚拟分配技术。 2、实验环境
Ubuntu 8.0或者以上,Eclipse集成开发环境 3、实验内容
3.1 观察Linux下的U盘访问
从键盘获得符号串,写入磁盘文件,然后读取该文件。
3.2 设备管理模拟实验要求:设计一个SPOOLing输入模拟系统。提示:输入井设计成结构体数组,每块存放一个输入文件内容。三个用户进程与一个后台输入进程并发执行,后台输入进程接受用户键盘输入的文件到输入井,每个用户进程从输入井获取输入数据。
老师所给的例子为为利用内存SPOOLing输入模拟系统,而问题的关键就是如何参考spoolout()设计spoolin()以及修改用户进程usepro()和输入#进程spoolsever()。
二、设计修改思路
spoolout()进程:键入要输入的用户id,如果用户输入文件未完成则键入文件内容,将文件内容mybuf发到输入井。
spoolsever()输入#进程:登记输入请求块,将缓冲区mybuf的数据送入输入井well。若成功送入,返回TRUE,否则返回FALSE。
usepro()用户进程:遍历输入请求块如找到该用户的输入请求,将输入请求块的数据送入用户缓冲区userbuf,并在屏幕输出userbuf。
三、实现修改的关键代码
#include
#define WELLSIZE 500 //输入井的大小 #define FALSE 0 #define TRUE 1
//进程控制块 struct {
int id; //进程标识数
char status; //进程状态,'e'为执行态,'c'为完成态。
int bufflag; //用户缓冲区userbuf空闲标志:FALSE为无数据,TRUE为有数据。
int filec; //本进程需要输出的文件数(用户指定)
}pcb[4]; //pcb[0]为SPOOLing进程,pcb[1]、pcb[2]、pcb[3]为3个用户进程
2
广西师范大学计算机科学与信息工程学院操作系统实验书
//输出请求块,共10块。可循环使用。 struct {
int reqid; //请求进程的标识数 int size; //输入文件长度
int addr; //输入文件在输出井well的指针 }reqblock[10];
int ebp=0; //输入请求块数组中的当前空闲块号。 int ebc=10; //输入请求块数组中的当前空闲块数 int cbp=0; //输入请求块数组的当前输出块号
char well[WELLSIZE]; //输入井,可以循环使用。 int wellptr=0;//输入井当前指针,环形指针。
int wellsize=WELLSIZE; //输入井剩余空闲区域大小 char userbuf[3][50]; //用户缓冲区 char mybuf[50]; //输入区
int file[4]; //4个进程输的文件数 int f[4]; //4个进程输入的文件数 int n; //输入文件总数
void main(); void scheduler(); float random() ;
void userpro(int idnum);
int spoolserver(int idnum,int charnum); void spoolin();
//------------------------------------------------------------------------------ void main() {
int i,j;
printf(\系统\\n\ //初始化
for (i=0;i for (i=0;i<3;i++)//初始化用户缓冲区 for(j=0;j<50;j++) userbuf[i][j]=0; for (i=0;i<4;i++) //初始化进程控制块 { pcb[i].id=i; pcb[i].status='e';//所有进程初始为可执行态 if (i) //对于用户进程 { 3 广西师范大学计算机科学与信息工程学院操作系统实验书 pcb[i].bufflag=FALSE; printf(\用户%d的输入文件数?\\n\ scanf(\ n+=pcb[i].filec; } } for (i=0;i<4;i++) f[i]=0; for (i=0;i<4;i++) file[i]=0; //调度进程执行 scheduler(); printf(\所有文件已经输入。结束!\\n\} //------------------------------------------------------------------------------------ //调度进程执行,直到所有数据输入完毕。 void scheduler() { float x; for (;;) { x=random(); if (x<0.4 && pcb[1].status=='e') userpro(1); else if (x>=0.4 && x<0.65 && pcb[2].status=='e') userpro(2); else if (x>=0.65 && x<0.95 && pcb[3].status=='e') userpro(3); else if (x>=0.95 && pcb[0].status=='e') spoolin();//执行SPOOLing进程 if (n==0) //所有文件输入完毕 break; } } //----------------------------------------------------------------------------------- float random() //产生随机数 { int m; static int seed; if ((m=seed)<0) 4 广西师范大学计算机科学与信息工程学院操作系统实验书 m=-m; seed=(25173*seed+13849)e536; return (m/32767.0); } //------------------------------------------------------------------------------------- void userpro(int idnum) { int i,k; int id,address,size,c,flag; flag=0; if (ebc<10) //有输出请求 { //取出当前输出请求块cbp的输出数据 for( i=0;i<10;i++) { if (reqblock[i].reqid==idnum) { flag=1;cbp=i;break; } } if(flag) { id=reqblock[cbp].reqid; size=reqblock[cbp].size; address=reqblock[cbp].addr;//数据在输入井的起始位置 // cbp=(++cbp);//指向下一个输出块(下一个可输出的块) printf(\ printf(\用户%d得到输入的第%d个文件,大小=%d个字符:\ address=address%WELLSIZE; //真正向设备输出数据。这里是向屏幕输出。 k=0; while((c=well[address++])!=0&&k k=0; while(userbuf[id][k]!=0&&k 5