实验五 磁盘文件操作

实验五  磁盘文件操作
实验五  磁盘文件操作

实验五磁盘文件操作

一、实验目的

深入了解磁盘文件系统的实现。

二、实验预备知识

文件的操作;

文件的逻辑结构和物理结构;

磁盘空间的管理;

磁盘目录结构。

三、实验内容

设计一个简单的文件系统,用文件模拟磁盘,用数组模拟缓冲区,要求实现:

支持多级目录结构,支持文件的绝对读路径;

文件的逻辑结构采用流式结构,物理结构采用链接结构中的显示链接方式;

采用文件分配表;

实现的命令包括建立目录、列目录、删除空目录、建立文件、删除文件、显示文件内容、打开文件、读文件、写文件(追加方式)、关闭文件、改变文件属性。

最后编写主函数对所做工作进行测试。

四、提示与讲解

为了正确地实现文件的存取,文件系统设计了一组与存取文件有关的功能模块,用户可以用“访管指令”调用这些功能模块,以实现文件的存取要求。我们把文件系统设计的这一组功能模块称为“文件操作”,实验就是要模拟实现一些文件操作。文件操作不是独立的,它和文件系统的其他部分密切相关,若要实现文件操作就离不开文件的目录结构、文件的组织结构和磁盘空间的管理。因此,这个实验虽然是文件操作的模拟实现,但是还必须模拟一部分文件的组织结构、目录结构和磁盘空间管理的实现。

(1)文件的组织结构

文件的逻辑结构有两种形式:流式文件和记录式文件。实验中只支持流式文件,采用称为显示链接的物理文件结构,把磁盘中每一块的指针部分提出来,组织在一起,形成文件分配表(FAT)。文件分配表的作用不仅如此,其他的作用下面将提到。

磁盘有多少块,文件分配表就有多少项,若某文件的一个磁盘块号为i,则这个文件的下一个磁盘的块号应该记录在文件分配表第i项。例如,某系统文件分配表前几项值如图10所示。某个文件的起始盘块号为3,则该文件的磁盘块号依次为3、4、9、12、13。

图10 某磁盘文件分配表部分内容

(2)磁盘空间的管理

首先要模拟一个磁盘。因为是实验,不使用真正的磁盘,所以实验中用一个文件模拟一个小磁盘。假设模拟磁盘有128个物理块,每个物理块大小为64字节。盘块的块号从0编起,0,1,2,3 (127)

将前面所讲的文件分配表放在磁盘的开始处,因为盘块有128块,所以文件分配表有

128项,每项占用一个字节。这样文件分配表占用了磁盘的0块和1块,这两块就不能作其他用处。若一个盘块是某个文件的最后一块,填写“-1”表示文件结束。

文件的建立和删除就需要对磁盘的空间进行分配和回收,所以要建立一定的数据表格来记录磁盘的使用情况。用文件分配表的第i项表示第i个盘块的使用情况。磁盘的第0块一定会被系统数据占用,所以任何一个文件的某个盘块块号都不可能是“0”,因而还可以用“0”表示磁盘盘块空闲,若这个盘块已经分配出去,即是某个文件的一块,由上面我们知道文件分配表中对应项记录的是文件下一块的块号或结束标志都不是“0”。这样非“0”值表示盘块已分。像前面图10那张文件分配表中,块号为5、14和15的盘块是空闲的,其余是已分配的。在文件分配表中可以用一个超过盘块编号的正整数表示文件结束,在此实验中采用255代替-1表示文件结束。

如果磁盘中某些部分损坏,只要不是系统区(引导扇区、文件分配表或根目录等),不分配那些坏的盘块,磁盘可以继续使用。在文件分配表对应坏盘块的项不能是“0”,一般也需要特定的数值表示(这个数值应该是盘块编号以外并且不是结束标志的数值,例如,实验中128~254之间的数值)。假设实验中模拟磁盘的第13块和第49块已经损坏,不能使用,则在文件分配表的第13项和第49项写入“254”表示该盘块损坏不能使用。

由于磁盘分配时,有时不能预定文件的大小,例如建立文件时并不知道文件的大小。因而磁盘的分配有时是一块一块申请的。磁盘空间回收时,整个文件删除时回收很多块,但有时文件修改时可能会删除某些内容,造成归还磁盘块,这时是一块一块回收的。这里给出申请一块磁盘空间的流程图,若分配多块时,循环多次即可。分配一个磁盘块时,不应该从文件分配表第一项查起,因为磁盘中最开始的几块为系统数据区(引导扇区、文件分配表、根目录等占用),所以应该从这之后的可分配数据区开始查询。假定系统区域占用了x个盘块,分配一个磁盘块的流程如图11所示。回收一个磁盘块的流程图很简单,比如回收磁盘块的块号为x,只要找到文件分配表中第x项,将第x项的值改为0即可。

图11 分配一个磁盘块的流程图

(3)目录结构

文件目录是用于检索文件的,它是文件系统实现按名存取的主要手段。文件目录由若干目录项组成,每一个目录记录一个文件的有关信息。一般地说,目录项应该包括如下内容:

①有关文件的控制信息。例如,用户名、文件名、文件类型、文件属性。实验模拟个人计算机上的文件操作,这部分内容仅包括文件名、文件类型和属性;

②有关文件结构的信息。例如,文件的逻辑结构、文件的物理结构、记录个数、文件在存储介质的位置等。实验中,仅仅支持流式文件,不支持记录式文件,所以这部分内容仅仅包括文件在存储介质的位置(分给文件第一个盘块的块号,即起始盘块号)、文件的长度;

③有关文件管理的信息。例如,文件的建立日期、文件被修改的日期、文件保留期限和记帐信息等。实验中为了简单起见,这部分内容都不采用。

因此,实验中文件的目录项包括:文件名、文件类型、文件属性、文件的起始盘块号、文件的长度,每个目录项占用8个字节,具体结构如下所示:

文件名:3个字节(实验中合法文件名仅可以使用字母、数字和除“$”、“.”和“/”以外的字符,第一个字节的值为“$”时表示该目录为空目录项,文件名和类型名之间用“.”分隔,用“/”作为路径名中目录间分隔符);

文件类型名:2个字节;

文件属性:1字节;

起始盘块号:1个字节;

文件长度:1个字节(为了实验的简单,文件长度单位为盘块)。

有了文件目录后,当用户要求使用某个文件时,文件系统可以顺序查找目录项,并比较文件名,就可以找到指定文件的目录项,根据目录项中有关内容核对使用权限、并读出文件供用户使用。因此文件目录的组织和管理要便于检索和防止冲突。

在操作系统中目录就有根目录和子目录两种目录。除了文件需要登记形成目录外,还要登记子目录的情况。实验中,根目录固定位置、固定大小(可以登记有限个文件或子目录项),子目录像文件一样,可使用任何一个空闲磁盘块。为了实验简单,实验中根目录占用了一个盘块,子目录的长度没有采用可以任意长的方法,而是采用了定长的方法,每个子目录的长度也是一个盘块,只能放8个目录项。文件和目录的登记项是混在一起的,登记项的结构应该和文件目录一样,每个目录项占用8个字节,结构如下:

目录名:3个字节(实验中合法文件名仅可以使用字母、数字和除“$”、“.”、“/”以外的字符,第一个字节的值为“$”时表示该目录为空目录);

未使用2字节(在实验中填写空格);

目录属性:1字节;

起始盘块号:1个字节;

未使用1字节(在实验中填写“0”)。

在目录登记项中,系统为目录名后2个字节(对应文件类型名位置)填写空格,目录起始盘块号后1字节(对应文件长度位置)填写0。目录属性和文件属性占用同一个字节,为了区别目录和文件,该字节每一位代表不同的含义(为“1”表示“是”,为“0”表示“否”),如图12所示,第0位表示文件为只读文件,第1位表示文件为系统文件,第2位表示文件为一般可读、可写的普通文件,第3位表示该登记项不是文件的登记项,而是目录的登记项,其余几位闲置未用。如该字节为8(8=(00001000)2)表示该目录是一个目录的登记项,该字节为3(3=(00000011)2)表示该目录是一个只读系统文件的登记项,该字节为(4=(00000100)2)表示该目录是一个可读可写的普通文件。

第7位第6位第5位第4位第3位第2位第1位第0位

图12 属性字节各位作用示意图

目录检索的方法常用的是顺序检索,根据绝对路径名查找文件的方法一般如下:先找到根目录的起始盘块,一般根目录位置是固定的,实验中就是模拟磁盘的第2块,将该盘块读出;取出路径名中根目录后的目录名或文件名,和根目录中目录项依次比较,比较完一块,再根据文件分配表找到下一块,再读入比较,直到找到名字一致的目录项或根目录登记项均已查完为止;若没有找到,则查找失败,结束;若查找的是文件,结束;若查找的是目录,从找到的目录项中,取出目录的起始盘块号,读入此盘块,然后用上述相同的查找方法继续查找,直到找到该文件(或目录)或查找失败结束。

实验中,使用绝对路径查找文件(或目录)的流程如图13所示。

图13 使用绝对路径查找文件(目录)的流程图

查找文件除了绝对路径名外,还可以使用相对路径名。相对路径名是从当前目录出发到指定文件的路径。如果文件(或目录)在当前目录下,使用相对路径名查找速度比较快。和绝对路径的查找方法一样,只是查找的起点是当前目录,不是根目录。实验中只使用了绝对路径名。

(4)文件操作

确定文件组织结构、目录结构和磁盘空间管理的方法后,就可以模拟文件操作的实现。实验中文件操作包括建立文件(create_file)、打开文件(open_file)、关闭文件(close_file)、读文件(read_file)、写文件(write_file)、删除文件(delete_file)、显示文件内容(typefile)和改变文件属性(change),目录命令包括建立目录(md)、显示目录内容(dir)和删除空目录(rd)。在实验中没有程序调用这些指令,为了看到它们的模拟情况,从键盘输入选择指令来模拟用户程序的调用。

首先要建立一个“已打开文件表”,用来记录打开或建立文件的相关内容,结构如图14所示。

图14 已打开文件表结构

用数组模拟已打开文件表,数据结构定义如下:

#define n 5 //实验中系统允许打开文件的最大数量 typedef struct { int dnum; //磁盘盘块号 int bnum; //磁盘盘块内第几个字节 }pointer; //已打开文件表中读、写指针的结构 typedef struct {char name[20]; //文件绝对路径名

char attribute; //文件的属性,用1个字节表示,所以采用char 类型 int number; //文件起始盘块号 int length; //文件长度,文件占用的字节数 int flag; //操作类型,用“0”表示以读操作方式开文件,用“

1”表示写操作方式打开文件

pointer read; //读文件的位置,文件打开时dnum 为文件起始盘块号,bnum 为“0” pointer write; //写文件的位置,文件刚建立时dnum 为文件起始盘块号,bnum 为“0”,打开文件时dnum 和bnum 为文件的末尾位置 }OFILE; //已打开文件表项类型定义 struct

{OFILE file[n]; //已打开文件登记表 int length; //已打开文件登记表中登记的文件数量 }openfile; //已打开文件登记表定义

无论上述哪种文件操作都会涉及到已打开文件表,对于已打开文件表主要是查找、删除和插入操作。下面给出这三种操作的流程图,在已打开文件表中查找某文件是否存在的流程如图15所示,将某文件从已打开文件表中删除的流程如图16所示,将某个文件登记在已打开文件表的流程图如图17所示。

图15 在已打开文件表中查找某文件的流程图 图16 将某文件从已打开文件表中删除的流程图

图17 将某文件插入已打开文件表的流程图

(1)建立文件(create_file)

用户要把一个新文件放到存储介质上前,首先调用文件系统的“建立”操作。

“建立文件”的主要工作就是检查文件目录,确认无重名文件后,寻找空闲登记项进行登记;寻找空闲存储块(至少一块)以备存储文件信息或存放索引表,最后应该填写已打开文件表。

实验中需要的参数比较少,只要有文件名、文件属性就可以,create_file(文件名,文件属性)。

实验中,建立文件时给出文件名和文件属性,文件属性如果是只读性质则不能建立;文件建立时根据给定的文件路径名进行查找,如果父目录不存在,建立文件失败;如果存在,查看有无重名文件,如果有,则提示该文件已存在,建立文件失败;如无重名文件,则为该文件建立文件目录,并分配给它一个磁盘块;最后填写目录和已打开文件表。建立文件的流程如图18所示。

图18 模拟建立文件的流程图

(2)打开文件(open_file)

用户要求使用一个已经存在的文件时,首先执行“打开文件”操作。

实验中,所需参数有文件名、操作类型(读或写),open_file(文件名,操作类型)。

实验中,打开文件首先要检查该文件是否存在,不存在,打开失败;如果文件存在,还要检查打开方式,确保不能以写方式打开只读文件;最后填写已打开文件表,若文件已经打开则不需要填写已打开文件表,打开文件的流程如图19所示。

图19 打开文件的流程图

(3)读文件(read_file)

用户要求读文件信息时调用文件系统的“读文件”操作。

实验中,读文件的参数只需要文件名和读取长度,read_file(文件名,读取长度)。因为采用的是流式文件结构,所以读的长度用字节表示。

实验中,读文件操作的主要工作是查找已打开文件表中是否存在该文件;如果不存在,不能读;然后检查是否是以读方式打开文件,如果是以写方式打开文件,则不允许读;最后从已打开文件表中读出读指针,从这个位置上读出所需要长度,若所需长度没有读完已经遇到文件结束符,就终止读操作。实验中用“#”表示文件结束,读文件的流程如图20所示。

(4)写文件(write_file)

用户要求存取文件信息时调用文件系统的“写文件”操作。实验中,写文件的参数只需要文件名、存放准备写入磁盘信息的缓冲和写的长度,write_file(文件名,缓冲,写长度)。因为采用的是流式文件结构,所以写长度用字节表示。

实验中,写文件操作的主要工作是查找已打开文件表中是否存在该文件,如果不存在,不能写;如果存在,还要检查是否以写方式打开文件;如果不是,写方式打开文件,不能写;最后从已打开文件表中读出写指针,从这个位置上写入缓冲中的数据。

图20 读文件的流程图

写文件有两种情况,一种情况是建立文件后的写入,这种写比较简单,一边写一边申请空间即可完成;一种情况是文件打开后的写入,这个比较复杂,存在着文件中间修改的问题。实验中,第二种情况只完成了从文件末尾向后追加的功能,写文件的流程如图21所示。

图21 写文件的流程图

(5)关闭文件(close_file)

用户对文件读写完毕后需要调用文件系统的“关闭文件”操作。

实验中,关闭文件的参数只需要文件名,close_file(文件名)。

实验中关闭文件,首先要看该文件是否打开,如果没有打开,就不用关闭;如果已经打开,则检查打开方式,如果是写方式打开的,要追加文件结束符,修改目录项;最后从已打开文件表中删除对应项,关闭文件的流程如图22所示。

图22 模拟关闭文件的流程图

(6)删除文件(delete_file)

用户认为文件没有必要保存时需要调用文件系统的“删除文件”操作。实验中,删除文件时参数只要文件名,delete_file(文件名)。

实验中,删除文件操作的主要工作是检查文件是否存在;不存在,操作失败;如存在,查找该文件是否打开,如果打开不能删除;如果没有打开,则删除文件目录项并归还文件所占磁盘空间,删除文件的流程如图23所示。

(7)显示文件内容(typefile)

显示文件内容首先要找到该文件的目录登记项,如果文件不存在,指令执行失败;如果存在,查看文件是否打开,打开则不能显示文件内容;若没有打开,从目录中取出文件的起始盘块号,一块一块显示文件内容,显示文件内容的流程如图24所示。

图24 显示文件的流程图(8)改变文件属性(change)

改变文件属性,首先查找该文件,如果不存在,结束;如果存在,检查文件是否打开,

打开不能改变属性;没有打开,根据要求改变目录项中属性值。

实验中,首先要系统初始化,包括建立文件c模拟磁盘、初始化磁盘FAT、初始化根目

录为空目录项;然后,可以选择一项功能执行。

目录的操作命令:

①建立目录(md)

建立目录首先要找到建立目录的位置(父目录),然后查找该目录是否存在,如果父目

录不存在,不能建立;如果存在,查找是否存在同名目录,存在,不能建立;不存在,则查

找一个空目录项,为该目录申请一个盘块,并填写目录内容。

建立目录流程图如图25所示。

②显示目录内容(dir)

显示目录内容首先要找到该目录,如果目录不存在,指令执行失败;如果存在,一项一

项显示目录内容。显示目录内容的流程如图26所示。

③删除空目录(rd)

删除空目录首先要找到该目录,如果目录不存在,指令执行失败;如果存在,但是根目

录或非空目录,显示不能删除,操作失败;若是非空子目录,则删除其目录项并回收对应空

间。删除空目录的过程和删除文件的过程相似,流程可参考文件的删除过程。

另外注意,对磁盘文件进行读操作时,需要磁盘的一个盘块读入主存后才能进行处理,对磁盘文件进行写操作时,要写满缓冲后才写入磁盘。所以模拟文件操作时,不能将整个模拟磁盘的内容同时读入主存,应该当需要模拟磁盘的某个盘块内容时,从对应文件中读出;修改后需要写回模拟磁盘。实验中就是用这种方法模拟磁盘的输入输出。

实验中定义了两个数组buffer1和buffer2模拟缓冲。

实验中首先系统初始化,包括建立文件c模拟磁盘、初始化磁盘FAT和根目录初始为空目录项,然后选择各个命令进行测试。

五、课外题

在上述基础上,将磁盘文件系统改进为支持多级树型目录,支持相对路径,子目录可以任意长的文件系统。再添加文件的拷贝、移动指令和非空目录的删除指令。

六、参考程序

#define false 0

#define true 1

#include "stdio.h"

typedef struct

{ char name[3]; //文件或目录名

char type[2]; //文件类型名

char attribute; //属性

char address; //文件或目录的起始盘块号

char length; //文件长度,以盘块为单位

图25 建立目录的流程图

}content; //目录结构

#define n 5 //模拟实验中系统允许打开文件的最大数量typedef struct

{ int dnum; //磁盘盘块号

int bnum; //磁盘盘块内第几个字节

}pointer; //已打开文件表中读写指针的结构

图26 显示目录内容的流程图

typedef struct

{char name[20]; //文件绝对路径名

char attribute; //文件的属性,用1个字节表示,char类型

int number; //文件起始盘块号

int length; //文件长度,文件占用的字节数int flag;

//操作类型,用“0”表示以读操作方式开文件的,用“1”表示写操作方式打开文件的pointer read; //读文件的位置,文件刚打开时dnum为文件起始盘pointer write; //写文件的位置,文件刚建立时dnum为文件起始盘块号,bnum为“0”,文件打开时为文件的末尾

}OFILE; //已打开文件表项类型定义

struct

{OFILE file[n]; //已打开文件表

int length; //已打开文件表中登记的文件数量

}openfile; //已打开文件表定义

char buffer1[64]; //模拟缓冲1

content buffer2[8]; //模拟缓冲2

FILE *fc; //模拟磁盘的文件的指针

copen(x1,x2)

OFILE *x1,*x2;

{

strcpy(x1->name,x2->name);

x1->attribute=x2->attribute;

x1->number=x2->number;

x1->length=x2->length;

x1->flag=x2->flag;

x1->read.dnum=x2->read.dnum;

x1->read.bnum=x2->read.bnum;

x1->write.dnum=x2->write.dnum;

x1->write.bnum=x2->write.bnum;

}

sopen(name)

//在已打开文件表中查找文件name

char *name;

{int i;

i=0;

//依次查找已打开文件表

while(i

if(i>=openfile.length)

return(-1);

return(i);

}//查找函数sopen结束

dopen(name)

//在已打开文件表中删除文件name

char *name;

{int i;

i=sopen(name);

if(i==-1)

printf("文件未打开\n");

else

{copen(&openfile.file[i],&openfile.file[openfile.length-1]);

openfile.length--;

}

}//删除函数dopen结束

iopen(x)

//在已打开文件表中插入n文件x->ame

content *x;

{int i;

i=sopen(x->name);

if(i!=-1)

{printf("文件已经打开\n");

return(false);

}

else if(openfile.length==n)

{ printf("已打开文件表已满\n");

return(false);

}

else

{copen(&openfile.file[openfile.length],x);

openfile.length++;

return(true);

}

}//填写已打开文件表函数结束

allocate( )

//分配一个磁盘块,返回块号

{int i;

fseek(fc,0,SEEK_SET); //将模拟磁盘的文件指针移至模拟磁盘FAT表

fread(buffer1,64L,1,fc); //将FAT表中第一个盘块读入模拟缓冲buffer1中 for(i=3;i<63;i++)

if(buffer1[i]==0)

//FAT中的第i项为0,分配第i块磁盘块,修改FAT表,并且写回磁盘 { buffer1[i]=255;

fseek(fc,0,SEEK_SET);

fwrite (buffer1,64L,1,fc);

return(i); //返回磁盘号

}

fread(buffer1,64L,1,fc); //将FAT表中第二个盘块读入模拟缓冲buffer1中 for(i=0;i<63;i++)

if(buffer1[i]==0) //FAT中的第i项为0,分配第i+64块磁盘块,修改FAT表,并且写回磁盘

{ buffer1[i]=255;

fseek(fc,-64L,SEEK_CUR);

fwrite(buffer1,64L,1,fc);

return(i+64); //返回磁盘号

}

printf("已经没有磁盘空间\n");

return(false);

}//分配磁盘块函数结束

read_file(name,length)

//读文件函数,文件路径名name,读取长度length

char *name;

int length;

{int i,t;

char ch;

if((i=sopen(name))==-1)

{printf("文件没有打开或不存在\n");

return(false);

}

if(openfile.file[i].flag==1)

{printf("文件以写方式打开,不能读\n");

return(false);

}

t=0;

fseek(fc,openfile.file[i].read.dnum*64L,SEEK_SET);

fread(buffer1,64,1,fc);

while(t

{putchar(buffer1[openfile.file[i].read.bnum]);

//读出一个字符(这里是在屏幕上显示)

if((t+1)%64==0)putchar('\n');

//修改读指针

openfile.file[i].read.bnum++;

if(openfile.file[i].read.bnum>=64) //一块读完,读取下一个盘块

{fseek(fc,openfile.file[i].read.dnum/64*64, SEEK_SET);

fread(buffer1,64,1,fc);

openfile.file[i].read.dnum=buffer1[openfile.file[i].read.dnum%64];

//修改读指针

openfile.file[i].read.bnum=0;

fseek(fc,openfile.file[i].read.dnum*64L,SEEK_SET);

fread(buffer1,64,1,fc); //读取下一个

}

t++;

}

}//读函数结束

write_file(name,buff,length)

//写文件函数

char *name; //文件路径名

char *buff; //存放准备写入磁盘的内容

int length; //写入内容的长度

{int i,t,dd;

if((i=sopen(name))==-1) //文件不存在,无法写

{printf("文件没有打开或不存在\n");

return(false);

}

if(openfile.file[i].flag==0)

{printf("文件以读方式打开,不能写\n");

return(false);

}

t=0;

fseek(fc,openfile.file[i].write.dnum*64L, SEEK_SET);

fread(buffer1,64,1,fc);

while(t

{buffer1[openfile.file[i].write.bnum]=buff[t];

openfile.file[i].write.bnum++;

openfile.file[i].length++;

if(openfile.file[i].write.bnum>=64)

{fseek(fc, openfile.file[i].write.dnum*64L, SEEK_SET);

fwrite(buffer1,64,1,fc); //一块写完,写回磁盘

if((dd=allocate())==false)

{ openfile.file[i].write.bnum--;

printf("无磁盘空间,部分信息丢失,写失败\n");

return(false);

}//if

fseek(fc,openfile.file[i].write.dnum/64*64L, SEEK_SET);

fread(buffer1,64,1,fc);

buffer1[openfile.file[i].write.dnum%64]=dd;

fseek(fc,openfile.file[i].write.dnum/64*64L, SEEK_SET);

fwrite(buffer1,64,1,fc);

openfile.file[i].write.dnum=dd;

openfile.file[i].write.bnum=0;

}//if

t++;

}//while

fseek(fc, openfile.file[i].write.dnum*64L, SEEK_SET);

fwrite(buffer1,64,1,fc); //一块写完,写回磁盘

}//写函数结束

search(name,flag,dnum,bnum)

//查找路径名为name的文件或目录,返回该目录的起始盘块号

char *name;

int flag; //flag=8表示查找目录,否则为文件

int *dnum,*bnum; //返回文件或目录的目录项登记位置,盘块dnum中第bnum 项

{int k,i,s,t,j,last=0;

char pna[3],type[2];

if((strcmp(name,"")==0)||(strcmp(name,"/")==0))//根目录

return(2);

k=0;

if(name[0]=='/')k=1;

i=2; // i=根目录的起始盘块号

while(last!=1)

{// pna=从name中分离出"/"后一个目录名(或文件名)

for(s=0;name[k]!='.'&&name[k]!='/'&&s<3&&name[k]!='\0';s++,k++)

pna[s]=name[k];

for(;s<3;s++) //用空格补全名字长度

pna[s]=' ';

while(name[k]!='.'&&name[k]!='\0'&&name[k]!='/')//除去多余字符

k++;

type[0]=type[1]=' ';

if(name[k]=='.') //取文件类型名type

if(flag==8)

{printf("目录不应该有有类型名,查找失败\n");

return(false);

}

else

{//文件遇到类型名认为结束,后面的字符作废

k++;

if(name[k]!='\0')type[0]=name[k];

k++;

if(name[k]!='\0')type[1]=name[k];

if(name[k]!='\0'&&name[k+1]!='\0')

{ printf("文件名错误\n");

return(false);

}

last=1;

}

else

if(name[k]!='\0')k++;

if(name[k]=='\0')

last=1;

//查找名字等于pna的目录项

fseek(fc,i*64L,SEEK_SET);

fread(buffer2,64L,1,fc);

j=0;

if(last==1&&flag!=8) //查找名字pna、类型名type的文件目录项 while(j<8&&!(buffer2[j].attribute!=8&&buffer2[j].name[0]==pna[0]&&

buffer2[j].name[1]==pna[1]&&buffer2[j].name[2]==pna[2]&&

buffer2[j].type[0]==type[0]&&buffer2[j].type[1]==type[1]))

j++;

else //查找名字等于pna的目录项

while(j<8&&!(buffer2[j].attribute==8&&buffer2[j].name[0]==pna[0]&&buffer2 [j].name[1]==pna[1]&&buffer2[j].name[2]==pna[2]))

j++;

if(j<8) //找到该目录或文件

if(last==1) //查找结束

{*dnum=i;

*bnum=j;

return(buffer2[j].address);

}

else //查找还未结束

i=buffer2[j].address; //读取下一个盘块

else

{ printf("路径错误\n");

return(false);

}

}//while 查找结束

}//search()结束

create_file(name,attribute)

//建立文件函数,路径名name,文件属性attribute

char *name;

int attribute;

{int dnum,bnum,i,j,last,k,s,d,t,tt,b,dd,flag,dn,bn;

char dname[3],tname[2],pathname[20];

OFILE x;

if(attribute%2==1)

{printf("只读文件,无法写,不能建立\n");

return(false);

}

if(openfile.length==n)

{printf("已打开表已满,不能建立\n");

return(false);

}

//将name分成两部分,目录路径pathname和目录名dname

for(j=0;name[j]!='\0';j++) //查找最后一个“/”

if(name[j]=='/')s=j;

//分离目录路径

for(j=0;j

pathname[j]=name[j];

pathname[j]='\0';

//分离文件名

for(k=0,j=s+1;name[j]!='\0'&&k<3&&name[j]!='.';j++,k++)

dname[k]=name[j];

if(k==0)

{printf("错误文件名或目录名\n");

return(false);

}

for(;k<3;k++)

dname[k]=' ';

k=0;

if(name[j++]=='.') //分离类型名

{ for(;name[j]!='\0'&&k<2&&name[j]!='.';j++,k++)

tname[k]=name[j];

}

for(;k<2;k++)

tname[k]=' ';

if((d=search(pathname,8,&dn,&bn))==false) //找到目录路径

{printf("目录不存在,不能建立");

return(false);

}

//确认该目录不存在的同时查找空目录项

b=-1;

fseek(fc,d*64L,SEEK_SET);

fread(buffer2,64L,1,fc); //读出d盘块的内容

for(t=0;t<8;t++)

{if(buffer2[t].name[0]==dname[0]&&buffer2[t].name[1]==dname[1]&&buffer2[t ].name[2]==dname[2]&&buffer2[t].type[0]==tname[0]&&buffer2[t].type[1]==tn ame[1])

{//找到名字dname的文件,建立失败

printf("文件已经存在,不能建立\n");

return(false);

}

if(buffer2[t].name[0]=='$'&&b==-1)

b=t;

}//for

if(b==-1) //没有空目录项,建立失败

{ printf("目录无空间\n");

return(false);

}

if((dd=allocate( ))==false) //分配给建立目录的磁盘盘块dd { printf("建立文件失败\n");

return(false);

}

//填写目录项

for(i=0;i<3;i++)

buffer2[b].name[i]=dname[i];

for(i=0;i<2;i++)

buffer2[b].type[i]=tname[i];

buffer2[b].attribute=attribute;

buffer2[b].address=dd;

buffer2[b].length=0;

fseek(fc,d*64L,SEEK_SET);

fwrite(buffer2,64L,1,fc);

//填写已打开文件表

strcpy(https://www.360docs.net/doc/a72389871.html,,name);

MATLAB基本操作实验报告

南昌航空大学 数学与信息科学学院 实验报告 课程名称:数学实验 实验名称: MATLAB基本操作 实验类型:验证性■综合性□ 设计性□ 实验室名称:数学实验室 班级学号: 10 学生姓名:钟 X 任课教师(教师签名): 成绩: 实验日期: 2011-10- 10

一、实验目的 1、熟悉MATLAB基本命令与操作 2、熟悉MATLAB作图的基本原理与步骤 3、学会用matlab软件做图 二、实验用仪器设备、器材或软件环境 计算机MATLAB软件 三、实验原理、方案设计、程序框图、预编程序等 问题1:在区间【0,2π】画sinx 实验程序: >> x=linspace(0,2*pi,30); >> y=sin(x); >> plot(x,y) 问题2:在【0,2π】用红线画sinx,用绿圈画cosx,实验程序:

>> x=linspace(0,2*pi,30); >> y=sin(x); >> z=cos(x); >> plot(x,y,'r',x,z,'co') >> 问题3:在【0,π】上画y=sinx的图形。 实验程序: >> ezplot('sin(x)',[0,pi]) >> 问题4:在【0,π】上画x=cos3t,y=sin3t星形图形。

实验程序: >> ezplot('cos(t).^3','sin(t).^3',[0,pi]) >> 问题5:[-2,0.5],[0,2]上画隐函数 实验程序: >> ezplot('exp(x)+sin(x*y)',[-2,0.5,0,2]) >> 问题6:在[-2,2]范围内绘制tanh的图形。实验程序: >> fplot('tanh',[-2,2])

《操作系统原理》信管专业实验指导书资料

《操作系统原理》实验指导书 班级:_______________ 学号:_______________ 姓名:_______________ 山东建筑大学管理工程学院 信息管理与信息系统教研室

目录 引言 (1) 实验题目一 (2) 实验题目二 (4) 实验题目三 (6) 实验题目四 (8) 实验题目五 (10) 实验题目六 (12)

引言 操作系统是信息管理与信息系统专业一门重要的专业理论课程,了解和掌握操作系统的基本概念、功能和实现原理,对认识整个计算机系统的工作原理十分重要。 操作系统实验是操作系统课程的一个重要组成部分,通过试验环节的锻炼使同学们不仅能够对以前的所学过的基础知识加以巩固,同时能够通过上机实验,对操作系统的抽象理论知识加以理解,最终达到融会贯通的目的,因此,实验环节是同学们理解、掌握操作系统基本理论的一个重要环节。 本实验指导书,根据教材中的重点内容设定了相应的实验题目,由于实验课程的学时有限,我们规定了必做题目和选做题目,其中必做题目必须在规定的上机学时中完成,必须有相应的预习报告和实验报告。选做题目是针对有能力或感兴趣的同学利用课余时间或上机学时的剩余时间完成。

实验题目一:模拟进程创建、终止、阻塞、唤醒原语 一、题目类型:必做题目。 二、实验目的:通过设计并调试创建、终止、阻塞、唤醒原语功能,有助于对操作系统中进 程控制功能的理解,掌握操作系统模块的设计方法和工作原理。 三、实验环境: 1、硬件:PC 机及其兼容机。 2、软件:Windows OS ,Turbo C 或C++、VC++、https://www.360docs.net/doc/a72389871.html, 、Java 等。 四、实验内容: 1、设计创建、终止、阻塞、唤醒原语功能函数。 2、设计主函数,采用菜单结构(参见后面给出的流程图)。 3、设计“显示队列”函数,目的能将就绪、阻塞队列中的进程信息显示在屏幕上,以供 随时查看各队列中进程的变化情况。 五、实验要求: 1、进程PCB 中应包含以下内容: 2、系统总体结构: 其中: 进程名用P1,P2标识。 优先级及运行时间:为实验题目二做准备。 状态为:就绪、运行、阻塞,三种基本状态。 指针:指向下一个PCB 。

实验五 存储管理(二)

实验五存储管理(二) 学号:姓名:班级: 实验目的: 1. 了解虚拟存储器。 2. 掌握分页存储管理的原理,熟悉段式存储和段页式存储管理。 3. 掌握常用的页面置换算法。 实验内容: 一、选择: 1.可变分区方式常用的主存分配算法中,()总是找到能满足作业要求的最大空闲区分配 A、最佳适应算法 B、首次适应算法 C、最坏适应算法 D、循环首次适应算法 2.下列()存储方式不能实现虚拟存储器 A、分区 B、页式 C、段式 D、段页式 3.操作系统处理缺页中断时,选择一种好的调度算法对主存和辅存中的信息进行高效调度尽可能地避免() A、碎片 B、CPU空闲 C、多重中断 D、抖动 4.分页式存储管理的主要特点是() A、要求处理缺页中断 B、要求扩充主存容量 C、不要求作业装入到主存的连续区域 D、不要求作业全部同时装人主存 5.LRU页面调度算法淘汰()的页 A、最近最少使用 B、最近最久未使用 C、最先进入主存 D、将来最久使用 6.分区管理要求对每一个作业都分配()的主存单元 A、地址连续 B、若干地址不连续的 C、若干连续的页 D、若干不连续的帧 7.在存储管理中,采用覆盖与交换技术的目的是()

A、节省主存空间 B、物理上扩充主存容量 C、提高CPU的效率 D、实现主存共享 8.分页虚拟存储管理中,缺页中断时,欲调度一页进入主存中,内存己无空闲块,如何决定淘汰已在主存的块时,()的选择是很重要的 A、地址变换 B、页面调度算法 C、对换方式 D、覆盖技术 9.()存储管理兼顾了段式在逻辑上清晰和页式在存储管理上方便的优点 A、分段 B、分页 C、可变分区方式 D、段页式 10.在固定分区分配中,每个分区的大小是() A、随作业长度变化 B、相同 C、可以不同但预先固定 D、可以不同但根据作业长度固定 11.下述()页面置换算法会产生Belady现象 A、最佳置换算法 B、先进先出算法 C、LRU算法 D、Clock算法 12.在一个分页式存储管理系统中,页表的内容为: 若页的大小为4KB,则地址转换机构将相对地址0转换成的物理地址是()。 A.8192 B.4096 C.2048 D.1024 13.采用先进先出页面淘汰算法的系统中,一进程在内存占3块(开始为空),页面访问序列为1、2、3、4、1、2、5、1、2、3、4、5、6。运行时会产生()次缺页中断。 A.7 B.8 C.9 D.10 二、填空: 1.在分页式存储管理的页表里,主要应该包含和两个信息。 2.在请求分页式存储管理中,页面淘汰是由于引起的。

图的遍历操作实验报告

. .. . .. .. 实验三、图的遍历操作 一、目的 掌握有向图和无向图的概念;掌握邻接矩阵和邻接链表建立图的存储结构;掌握DFS及BFS对图的遍历操作;了解图结构在人工智能、工程等领域的广泛应用。 二、要求 采用邻接矩阵和邻接链表作为图的存储结构,完成有向图和无向图的DFS 和BFS操作。 三、DFS和BFS 的基本思想 深度优先搜索法DFS的基本思想:从图G中某个顶点Vo出发,首先访问Vo,然后选择一个与Vo相邻且没被访问过的顶点Vi访问,再从Vi出发选择一个与Vi相邻且没被访问过的顶点Vj访问,……依次继续。如果当前被访问过的顶点的所有邻接顶点都已被访问,则回退到已被访问的顶点序列中最后一个拥有未被访问的相邻顶点的顶点W,从W出发按同样方法向前遍历。直到图中所有的顶点都被访问。 广度优先算法BFS的基本思想:从图G中某个顶点Vo出发,首先访问Vo,然后访问与Vo相邻的所有未被访问过的顶点V1,V2,……,Vt;再依次访问与V1,V2,……,Vt相邻的起且未被访问过的的所有顶点。如此继续,直到访问完图中的所有顶点。 四、示例程序 1.邻接矩阵作为存储结构的程序示例

#include"stdio.h" #include"stdlib.h" #define MaxVertexNum 100 //定义最大顶点数 typedef struct{ char vexs[MaxVertexNum]; //顶点表 int edges[MaxVertexNum][MaxVertexNum]; //邻接矩阵,可看作边表int n,e; //图中的顶点数n和边数e }MGraph; //用邻接矩阵表示的图的类型 //=========建立邻接矩阵======= void CreatMGraph(MGraph *G) { int i,j,k; char a; printf("Input VertexNum(n) and EdgesNum(e): "); scanf("%d,%d",&G->n,&G->e); //输入顶点数和边数 scanf("%c",&a); printf("Input Vertex string:"); for(i=0;in;i++) { scanf("%c",&a); G->vexs[i]=a; //读入顶点信息,建立顶点表 }

操作系统原理-进程调度实验报告

一、实验目的 通过对进程调度算法的设计,深入理解进程调度的原理。 进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。 进程调度分配处理机,是控制协调进程对CPU的竞争,即按一定的调度算法从就绪队列中选中一个进程,把CPU的使用权交给被选中的进程。 进程通过定义一个进程控制块的数据结构(PCB)来表示;每个进程需要赋予进程ID、进程到达时间、进程需要运行的总时间的属性;在RR中,以1为时间片单位;运行时,输入若干个进程序列,按照时间片输出其执行序列。 二、实验环境 VC++6.0 三、实验内容 实现短进程优先调度算法(SPF)和时间片轮转调度算法(RR) [提示]: (1) 先来先服务(FCFS)调度算法 原理:每次调度是从就绪队列中,选择一个最先进入就绪队列的进程,把处理器分配给该进程,使之得到执行。该进程一旦占有了处理器,它就一直运行下去,直到该进程完成或因发生事件而阻塞,才退出处理器。 将用户作业和就绪进程按提交顺序或变为就绪状态的先后排成队列,并按照先来先服务的方式进行调度处理,是一种最普遍和最简单的方法。它优先考虑在系统中等待时间最长的作业,而不管要求运行时间的长短。 按照就绪进程进入就绪队列的先后次序进行调度,简单易实现,利于长进程,CPU繁忙型作业,不利于短进程,排队时间相对过长。 (2) 时间片轮转调度算法RR

原理:时间片轮转法主要用于进程调度。采用此算法的系统,其程序就绪队列往往按进程到达的时间来排序。进程调度按一定时间片(q)轮番运行各个进程. 进程按到达时间在就绪队列中排队,调度程序每次把CPU分配给就绪队列首进程使用一个时间片,运行完一个时间片释放CPU,排到就绪队列末尾参加下一轮调度,CPU分配给就绪队列的首进程。 固定时间片轮转法: 1 所有就绪进程按 FCFS 规则排队。 2 处理机总是分配给就绪队列的队首进程。 3 如果运行的进程用完时间片,则系统就把该进程送回就绪队列的队尾,重新排队。 4 因等待某事件而阻塞的进程送到阻塞队列。 5 系统把被唤醒的进程送到就绪队列的队尾。 可变时间片轮转法: 1 进程状态的转换方法同固定时间片轮转法。 2 响应时间固定,时间片的长短依据进程数量的多少由T = N × ( q + t )给出的关系调整。 3 根据进程优先级的高低进一步调整时间片,优先级越高的进程,分配的时间片越长。 多就绪队列轮转法: (3) 算法类型 (4)模拟程序可由两部分组成,先来先服务(FCFS)调度算法,时间片轮转。流程图如下:

实验五 动态分区存储管理

实验五动态分区存储管理 一、实验目的 深入了解采用动态分区存储管理方式的内存分配回收的实现。通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解,熟悉动态分区存储管理的内存分配和回收。 二、实验内容 编写程序完成动态分区存储管理方式的内存分配回收。 具体包括:确定内存空间分配表; 采用最优适应算法完成内存空间的分配和回收; 编写主函数对所做工作进行测试。 三、设计思路 整体思路: 动态分区管理方式将内存除操作系统占用区域外的空间看成一个大的空闲区。当作业要求装入内存时,根据作业需要内存空间的大小查询内存中的各个空闲区,当从内存空间中找到一个大于或等于该作业大小的内存空闲区时,选择其中一个空闲区,按作业需求量划出一个分区装人该作业,作业执行完后,其所占的内存分区被收回,成为一个空闲区。如果该空闲区的相邻分区也是空闲区,则需要将相邻空闲区合并成一个空闲区。 设计所采用的算法: 采用最优适应算法,每次为作业分配内存时,总是把既能满足要求、又是最小的空闲分区分配给作业。但最优适应算法容易出现找到的一个分区可能只比作业所需求的长度略大一点的情行,这时,空闲区分割后剩下的空闲区就很小以致很难再使用,降低了内存的使用率。为解决此问题,设定一个限值minsize,如果空闲区的大小减去作业需求长度得到的值小于等于minsize,不再将空闲区分成己分分区和空闲区两部分,而是将整个空闲区都分配给作业。 内存分配与回收所使用的结构体: 为便于对内存的分配和回收,建立两张表记录内存的使用情况。一张为记录作业占用分 区的“内存分配表”,内容包括分区起始地址、长度、作业名/标志(为0时作为标志位表示空栏目);一张为记录空闲区的“空闲分区表”,内容包括分区起始地址、长度、标志(0表空栏目,1表未分配)。两张表都采用顺序表形式。

实验报告1windows的基本操作范例

实验名称:Windows的基本操作 一、实验目的 1.掌握桌面主题的设置。 2.掌握快捷方式的创建。 3.掌握开始菜单的组织。 4.掌握多任务间的数据传递——剪贴板的使用。 5.掌握文件夹和文件的创建、属性查看和设置。 6.掌握文件夹和文件的复制、移动和删除与恢复。 7.熟悉文件和文件夹的搜索。 8.熟悉文件和文件夹的压缩存储和解压缩。 二、实验环境 1.中文Windows 7操作系统。 三、实验内容及步骤 通过上机完成实验4、实验5所有内容后完成该实验报告 1.按“实验4--范例内容(1)”的要求设置桌面,将修改后的界面复制过来。 注:没有桌面背景图“Autumn”的,可选择其它背景图。 步骤:在桌面空白区域右击,选择菜单中的“个性化”,在弹出的窗口中点击“桌面背景”,在背景栏内选中“某一张图片”,单击“确定”。 修改后的界面如下图所示: 2.将画图程序添加到“开始”菜单的“固定项目列表”上。 步骤:右击“开始/所有程序/附件”菜单中的画图程序项,在弹出的快捷菜单中选“附到「开始」菜单”命令。 3.在D盘上建立以“自己的学号+姓名”为名的文件夹(如01108101刘琳)和其子文件 夹sub1,然后:

步骤:选定D:\为当前文件夹,选择“文件/新建/文件夹”命令,并将名字改为“学号+姓名”;选定“ D:\学号+姓名”为当前文件夹,选择“文件/新建/文件夹”命令,并将名字改为“sub1” ①在C:\WINDOWS中任选2个TXT文本文件,将它们复制到“学号+姓名”文件夹中;步骤:选定“C:\WINDOWS”为当前文件夹,随机选取2个文件, CTRL+C复制,返回“D:\学号+姓名”的文件夹,CTRL+V粘贴 ②将“学号+姓名”文件夹中的一个文件移到其子文件夹sub1中; 步骤:选定“ D:\学号+姓名”为当前文件夹,选中其中任意一个文件将其拖拽文件到subl ③在sub1文件夹中建立名为“”的空文本文档; 步骤:选定“ D:\学号+姓名\ sub1”为当前文件夹,在空白处单击右键,选择“新建\文本文档”,把名字改为test,回车完成。 ④删除文件夹sub1,然后再将其恢复。 步骤:选定“ D:\学号+姓名”为当前文件夹,右键单击“sub1”文件夹,选择“删除”,然后打开回收站,右键单击“sub1”文件夹,在弹出的快捷菜单中选择“还原”。 4.搜索C:\WINDOWS\system文件夹及其子文件夹下所有文件名第一个字母为s、文件长 度小于10KB且扩展名为exe的文件,并将它们复制到sub1文件夹中。 步骤:选定“ C:\WINDOWS\system”为当前文件夹,单击“搜索”按钮,在左侧窗格选择“所有文件和文件夹”,在“全部或部分文件名”中输入“s*.exe”,在“大小”中,选择“0~10KB”。 5.用不同的方法,在桌面上创建名为“计算器”、“画图”和“剪贴板”的三个快捷方式, 它们应用程序分别为:、和。并将三个快捷方式复制到sub1文件夹中。 步骤:①在"开始"菜单的"所有程序"子菜单中找到"计算器",单击右键,在弹出的快捷菜单中选择“发送到\桌面快捷方式”。 ②在"开始"菜单的"所有程序"子菜单中找到"画图",将其拖至桌面空白处。 ③在桌面上单击右键,在弹出的快捷菜单中选择“新建\快捷方式”,在“创建快捷方式”

操作系统原理实验-系统内存使用统计5

上海电力学院 计算机操作系统原理 实验报告 题目:动态链接库的建立与调用 院系:计算机科学与技术学院 专业年级:信息安全2010级 学生姓名:李鑫学号:20103277 同组姓名:无 2012年11 月28 日上海电力学院

实验报告 课程名称计算机操作系统原理实验项目线程的同步 姓名李鑫学号20103277 班级2010251班专业信息安全 同组人姓名无指导教师姓名徐曼实验日期2012/11/28 实验目的和要求: (l)了解Windows内存管理机制,理解页式存储管理技术。 (2)熟悉Windows内存管理基本数据结构。 (3)掌握Windows内存管理基本API的使用。 实验原理与内容 使用Windows系统提供的函数和数据结构显示系统存储空间的使用情况,当内存和虚拟存储空间变化时,观察系统显示变化情况。 实验平台与要求 能正确使用系统函数GlobalMemoryStatus()和数据结构MEMORYSTATUS了解系统内存和虚拟空间使用情况,会使用VirtualAlloc()函数和VirtualFree()函数分配和释放虚拟存储空间。 操作系统:Windows 2000或Windows XP 实验平台:Visual Studio C++ 6.0 实验步骤与记录 1、启动安装好的Visual C++ 6.0。 2、选择File->New,新建Win32 Console Application程序, 由于内存分配、释放及系统存储 空间使用情况均是Microsoft Windows操作系统的系统调用,因此选择An application that support MFC。单击确定按钮,完成本次创建。 3、创建一个支持MFC的工程,单击完成。

操作系统原理实验指导

操作系统实验指导 操作系统是计算机的最重要的系统软件,它在计算机中具有核心地位,其作用是对计算机系统资源进行统一的调度和管理,提供各种强有力的系统服务,为用户创造灵活而又方便的使用环境。一个精心设计的操作系统能极大地扩充计算机系统的功能,充分地发挥系统中各种资源的使用效率,提高系统工作的可靠性。 操作系统原理是计算机科学与技术专业的一门主要专业课程,它涉及计算机系统中各种软、硬资源管理的实现原理与方法,内容非常丰富,综合性非常强,并且还具有很强的实践性。只有把理论与实践紧密地结合起来,才能取得较好地学习效果。 培养计算机专业学生的系统程序设计能力,也是本课程的重要环节。系统程序要求结构清晰、合理、可读性好,有准确而简明的注释。通过实验可以培养学生正规系统程序设计能力。 本实验包括下列六个方面: 实验一几种操作系统的界面 实验二进程调度 实验三存储器管理 实验四存储器管理 实验五磁盘驱动调度 实验六文件管理系统 上述每个实验约需要10个学时。可根据实际情况选用。最好学生自己独立完成,如有困难,可参考一些示例,弄清每个实验的思想和实现方法,上机调试通过,不能完全照搬示例。 实验一几种操作系统的界面 1、目的与要求 目的:通过本实验,学生应熟悉1~2种操作系统的界面。在熟练使用的基础上,能了解各种命令和调用在系统中的大致工作过程,也就是通过操作系统的外部特性,逐步深入到操作系统的内在实质内容中去。 要求:能熟练地在1~2种操作系统环境下工作。学会使用各种命令,熟悉系统提供的各种功能。主动而有效地使用计算机。 熟悉系统实用程序的调用方法和各种系统调用模块的功能和用法。 2、示例 用1~2种操作系统提供的各种手段,建立、修改、编辑、编译和运行程序,最后撤消一个简单程序。要尽可能多地使用系统提供的各种命令和功能。 操作系统可为如下两种序列: (1)Windows 98或Windows 2000或Windows XP。 (2)Linux或Unix。 下面简要介绍一下Unix操作系统。 Unix是一个分时操作系统,面向用户的界面shell是一种命令程序设计语言,这种语言向用户提供了从低到高,从简单到复杂的三个层次的使用方式。它们是简单命令、组合命令和shell过程。 简单命令:Unix命令一律使用小写字母。 例如:ls -l 显示文件目录(长格式) rm 删除一个文件 cat 合并和传送文件、 cp 复制文件 mv 文件改名 cc 编译C语言源程序 组合命令:shell简单命令可以用管道算符|组合构成功能更强的命令。

实验操作系统存储管理实验报告

实验四操作系统存储管理实验报告 一、实验目的 存储管理的主要功能之一是合理地分配空间。请求页式管理是一种常用的虚拟存储管理技术。 本实验的目的是通过请求页式管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。 二、实验内容 (1)通过计算不同算法的命中率比较算法的优劣。同时也考虑了用户内存容量对命中率的影响。 页面失效次数为每次访问相应指令时,该指令所对应的页不在内存中的次数。 在本实验中,假定页面大小为1k,用户虚存容量为32k,用户内存容量为4页到32页。 (2)produce_addstream通过随机数产生一个指令序列,共320条指令。 A、指令的地址按下述原则生成: 1)50%的指令是顺序执行的 2)25%的指令是均匀分布在前地址部分 3)25%的指令是均匀分布在后地址部分 B、具体的实施方法是: 1)在[0,319]的指令地址之间随机选取一起点m; 2)顺序执行一条指令,即执行地址为m+1的指令; 3)在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’; 4)顺序执行一条指令,地址为m’+1的指令 5)在后地址[m’+2,319]中随机选取一条指令并执行; 6)重复上述步骤1)~5),直到执行320次指令 C、将指令序列变换称为页地址流

在用户虚存中,按每k存放10条指令排列虚存地址,即320条指令在虚存中 的存放方式为: 第0条~第9条指令为第0页<对应虚存地址为[0,9]); 第10条~第19条指令为第1页<对应虚存地址为[10,19]); 。。。。。。 第310条~第319条指令为第31页<对应虚存地址为[310,319]); 按以上方式,用户指令可组成32页。 (3)计算并输出下属算法在不同内存容量下的命中率。 1)先进先出的算法

数据结构实验图的基本操作

浙江大学城市学院实验报告 课程名称数据结构 实验项目名称实验十三/十四图的基本操作 学生姓名专业班级学号 实验成绩指导老师(签名)日期2014/06/09 一.实验目的和要求 1、掌握图的主要存储结构。 2、学会对几种常见的图的存储结构进行基本操作。 二.实验内容 1、图的邻接矩阵定义及实现: 建立头文件test13_AdjM.h,在该文件中定义图的邻接矩阵存储结构,并编写图的初始化、建立图、输出图、输出图的每个顶点的度等基本操作实现函数。同时建立一个验证操作实现的主函数文件test13.cpp(以下图为例),编译并调试程序,直到正确运行。 2、图的邻接表的定义及实现: 建立头文件test13_AdjL.h,在该文件中定义图的邻接表存储结构,并编写图的初始化、建立图、输出图、输出图的每个顶点的度等基本操作实现函数。同时在主函数文件test13.cpp中调用这些函数进行验证(以下图为例)。

3、填写实验报告,实验报告文件取名为report13.doc。 4、上传实验报告文件report13.doc到BB。 注: 下载p256_GraphMatrix.cpp(邻接矩阵)和 p258_GraphAdjoin.cpp(邻接表)源程序,读懂程序完成空缺部分代码。 三. 函数的功能说明及算法思路 (包括每个函数的功能说明,及一些重要函数的算法实现思路) 四. 实验结果与分析 (包括运行结果截图、结果分析等)

五.心得体会

程序比较难写,但是可以通过之前的一些程序来找到一些规律 (记录实验感受、上机过程中遇到的困难及解决办法、遗留的问题、意见和建议等。) 【附录----源程序】 256: //p-255 图的存储结构以数组邻接矩阵表示, 构造图的算法。 #include #include #include #include typedef char VertexType; //顶点的名称为字符 const int MaxVertexNum=10; //图的最大顶点数 const int MaxEdgeNum=100; //边数的最大值 typedef int WeightType; //权值的类型 const WeightType MaxValue=32767; //权值的无穷大表示 typedef VertexType Vexlist[MaxVertexNum]; //顶点信息,定点名称 typedef WeightType AdjMatrix[MaxVertexNum][MaxVertexNum]; //邻接矩阵typedef enum{DG,DN,AG,AN} GraphKind; //有向图,有向网,无向图,无向网typedef struct{ Vexlist vexs; // 顶点数据元素 AdjMatrix arcs; // 二维数组作邻接矩阵 int vexnum, arcnum; // 图的当前顶点数和弧数 GraphKind kind; // 图的种类标志 } MGraph; void CreateGraph(MGraph &G, GraphKind kd)// 采用数组邻接矩阵表示法,构造图G {//构造有向网G int i,j,k,q; char v, w; G.kind=kd; //图的种类 printf("输入要构造的图的顶点数和弧数:\n"); scanf("%d,%d",&G.vexnum,&G.arcnum); getchar();//过滤回车 printf("依次输入图的顶点名称ABCD...等等:\n"); for (i=0; i

实验指导(2015完全版)

操作系统上机实验指导书 (第一版) 闫大顺李晟编著 吴家培主审 计算机科学与工程学院 2014.8

操作系统实验指导 本课程是为《计算机操作系统》课所开的实验。计算机操作系统课程是一门实践性很强的技术课程,本课程实验的目的在于培养学生的实践能力,促进理论与实践的结合。要求学生通过上机编程,熟悉对操作系统原理,并熟练使用程序接口,并了解如何模拟操作系统原理的实现,从而加深对操作系统原理的领会,加深对操作系统实现方法的理解,与此同时使学生在程序设计方面也能够得到很大程度的提高。 实验的目的是使学生理论联系实际,提高学生系统理解与开发能力。这里所列的实验分为必做和选做。具体实验题的选择,不仅要考虑课程内容,而且要考虑学生目前的编程能力,要由浅入深。教师可通过运行示例或动画,帮助学生理解实验要求。学生应选择自己熟悉的语言与开发环境去完成实验。根据以往的教学经验,Delphi、C++ Builder,JBuilder由于提供了许多可重用的构件,易于学习、使用,VC++学习、使用困难较多。实验要求尽量在windows操作系统下,也可以在Linux下完成,由于多数没有专门学习Linux,在其平台下做试验比较困难。实验的硬件要求是能够支持VC++、Delphi、C++ Builder,JBuilder的微机即可。每个学生都独立在一台计算机上完成自己的实验内容,杜绝学生的抄袭。 实验报告的要求 1. 每位同学准备实验报告本,上机前作好充分的准备工作,预习本次实验的内容,事先熟悉与实验有关的软硬件环境。 2. 实验时遵守实验室的规章制度,爱护实验设备,对于实验设备出现的问题,要及时向指导老师汇报。 3. 提交实验文件格式:[班级][学号]_[实验题号].[扩展名] 例:计051班学号为03的学生第四个实验的文件名为:j05103_4.c 4. 最终的实验报告按照实验名称、实验目的、实验内容,实验过程(程序设计、实现与调试)、实验总结五部分书写,按时上交。实验总结是对于实验过程中出现的问题或疑惑的分析与思考。认真按照要求填写到实验报告纸上。

实验五动态分区存储管理模拟

实验五动态分区存储管理模拟 一、实验目的 深入了解可变分区存储管理式主存分配回收的实现。 二、实验预备知识 可变分区存储管理式不预先将主存划分成几个区域,而把主存除操作系统占用区域外的空间看作一个大的空闲区。当进程要求装入主存时,根据进程需要主存空间的大小查询主存各个空闲区,当从主存空间找到一个大于或等于该进程大小要求的主存空闲区时,选择其中一个空闲区,按进程需求量划出一个分区装入该进程。进程执行完后,它所占的主存分区被回收,成为一个空闲区。如果该空闲区的相邻分区也是空闲区,则需要将相邻空闲区合并成一个空闲区。 这个实验主要需要考虑三个问题: (1)设计记录主存使用情况的数据表格,用来记录空闲区和进程占用的区域; (2)在设计的数据表格基础上设计主存分配算法; (3)在设计的数据表格基础上设计主存回收算法。 首先,考虑第一个问题:设计记录主存使用情况的数据表格,用来记录空闲区和进程占用的区域。 由于可变分区的大小是由进程需求量决定的,故分区的长度是预先不固定的,且分区的个数也随主存分配和回收而变动。总之,所有分区情况随时可能发生变化,数据表格的设计必须和这个特点相适应。由于分区长度不同,因此设计的表格应该包括分区在主存中的起始地址和长度。由于分配时空闲区有时会变成两个分区:空闲区和已分分区,回收主存分区时,可能会合并空闲分区,这样如果整个主存采用一表格记录已分分区和空闲区,就会使表格操作繁琐。主存分配

时查找空闲区进行分配,然后填写已分分区表,主要操作在空闲区;某个进程执行完成后,将该分区变成空闲区,并将其与相邻空闲区合并,主要操作也在空闲区。由此可见,主存分配和回收主要是对空闲区的操作。 这样,为了便于对主存空间的分配和回收,就建立两分区表记录主存使用情况,一表格记录进程占用分区的“已分分区表”;一是记录空闲区的“空闲区表”。这两表的实现法一般有两种,一种是链表形式,一种是顺序表形式。在实验中,采用顺序表形式,用数组模拟。由于顺序表的长度必须提前固定,所以无论是“已分分区表”还是“空闲区表”都必须事先确定长度。它们的长度必须是系统可能的最大项数,系统运行过程中才不会出错,因而在多数情况下,无论是“已分分区表”还是“空闲区表”都有空闲栏目。已分分区表中除了分区起始地址、长度外,也至少还要有一项“标志”,如果是空闲栏目,容为“空”,如果为某个进程占用分区的登记项,容为该进程的进程名;空闲区表中除了分区起始地址、长度外,也要有一项“标志”,如果是空闲栏目,容为“空”,如果为某个空闲区的登记项,容为“未分配”。在实际系统中,这两个表格的容可能还要更多,实验中仅仅使用上述必须的数据。为此,“已分分区表”和“空闲区表”在实验中有如下的结构定义: 已分分区表的定义: #define n 10 //假定系统允的进程数量最多为n struct { float address; //已分分区起始地址 float length; //已分分区长度,单位为字节

数字图像处理实验报告

目录 实验一:数字图像的基本处理操作 (4) :实验目的 (4) :实验任务和要求 (4) :实验步骤和结果 (5) :结果分析 (8) 实验二:图像的灰度变换和直方图变换 (9) :实验目的 (9) :实验任务和要求 (9) :实验步骤和结果 (9) :结果分析 (13) 实验三:图像的平滑处理 (14) :实验目的 (14) :实验任务和要求 (14) :实验步骤和结果 (14) :结果分析 (18) 实验四:图像的锐化处理 (19) :实验目的 (19) :实验任务和要求 (19) :实验步骤和结果 (19) :结果分析 (21)

实验一:数字图像的基本处理操作 :实验目的 1、熟悉并掌握MATLAB、PHOTOSHOP等工具的使用; 2、实现图像的读取、显示、代数运算和简单变换。 3、熟悉及掌握图像的傅里叶变换原理及性质,实现图像的傅里叶变换。:实验任务和要求 1.读入一幅RGB图像,变换为灰度图像和二值图像,并在同一个窗口内分 成三个子窗口来分别显示RGB图像和灰度图像,注上文字标题。 2.对两幅不同图像执行加、减、乘、除操作,在同一个窗口内分成五个子窗口来分 别显示,注上文字标题。 3.对一幅图像进行平移,显示原始图像与处理后图像,分别对其进行傅里叶变换, 显示变换后结果,分析原图的傅里叶谱与平移后傅里叶频谱的对应关系。 4.对一幅图像进行旋转,显示原始图像与处理后图像,分别对其进行傅里 叶变换,显示变换后结果,分析原图的傅里叶谱与旋转后傅里叶频谱的 对应关系。 :实验步骤和结果 1.对实验任务1的实现代码如下: a=imread('d:\'); i=rgb2gray(a); I=im2bw(a,; subplot(1,3,1);imshow(a);title('原图像'); subplot(1,3,2);imshow(i);title('灰度图像'); subplot(1,3,3);imshow(I);title('二值图像'); subplot(1,3,1);imshow(a);title('原图像'); 结果如图所示:

操作系统原理实验四

实验4 进程控制 1、实验目的 (1)通过对WindowsXP进行编程,来熟悉和了解系统。 (2)通过分析程序,来了解进程的创建、终止。 2、实验工具 (1)一台WindowsXP操作系统的计算机。 (2)计算机装有Microsoft Visual Studio C++6.0专业版或企业版。 3、预备知识 (3)·CreateProcess()调用:创建一个进程。 (4)·ExitProcess()调用:终止一个进程。 4、实验编程 (1)编程一利用CreateProcess()函数创建一个子进程并且装入画图程序(mspaint.exe)。阅读该程序,完成实验任务。源程序如下: # include < stdio.h > # include < windows.h > int main(VOID) ﹛STARTUPINFO si; PROCESS INFORMA TION pi; ZeroMemory(&si,sizeof(si)); Si.cb=sizeof(si); ZeroMemory(&pi,sizeof(pi)); if(!CreateProcess(NULL, “c: \ WINDOWS\system32\ mspaint.exe”, NULL, NULL, FALSE, 0, NULL, NULL, &si,&pi)) ﹛fprintf(stderr,”Creat Process Failed”); return—1; ﹜ WaitForSingleObject(pi.hProcess,INFINITE); Printf(“child Complete”); CloseHandle(pi.hProcess); CloseHandle(pi hThread); ﹜

实验五动态页式存储管理实现过程的模拟

实验五动态页式存储管理实现过程的模拟 一、实验目的与要求 在计算机系统中,为了提高主存利用率,往往把辅助存储器(如磁盘)作为主存储器的扩充,使多道运行的作业的全部逻辑地址空间总和可以超出主存的绝对地址空间。用这种办法扩充的主存储器称为虚拟存储器。通过本实验帮助学生理解在分页式存储管理中怎样实现虚拟存储器;掌握物理内存和虚拟内存的基本概念;掌握重定位的基本概念及其要点,理解逻辑地址与绝对地址;掌握动态页式存储管理的基本原理、地址变换和缺页中断、主存空间的分配及分配算法;掌握常用淘汰算法。 二、实验环境 VC++6.0集成开发环境或java程序开发环境。 三、实验内容 模拟分页式虚拟存储管理中硬件的地址转换和缺页中断,以及选择页面调度算法处理缺页中断。 四、实验原理 1、地址转换 (1)分页式虚拟存储系统是把作业信息的副本存放在磁盘上,当作业被选中时,可把作业的开始几页先装入主存且启动执行。为此,在为作业建立页表时,应说明哪些页已在主存,哪些页尚未装入主存,页表的格式如图10所示: 图10 页表格式 其中,标志----用来表示对应页是否已经装入主存,标志位=1,则表示该页已经在主存,标志位=0,则表示该页尚未装入主存。 主存块号----用来表示已经装入主存的页所占的块号。

在磁盘上的位置----用来指出作业副本的每一页被存放在磁盘上的位置。 (2)作业执行时,指令中的逻辑地址指出了参加运算的操作存放的页号和单元号,硬件的地址转换机构按页号查页表,若该页对应标志为“1”,则表示该页已在主存,这时根据关系式: 绝对地址=块号×块长+单元号 计算出欲访问的主存单元地址。如果块长为2的幂次,则可把块号作为高地址部分,把单元号作为低地址部分,两者拼接而成绝对地址。若访问的页对应标志为“0”,则表示该页不在主存,这时硬件发“缺页中断”信号,有操作系统按该页在磁盘上的位置,把该页信息从磁盘读出装入主存后再重新执行这条指令。 (3)设计一个“地址转换”程序来模拟硬件的地址转换工作。当访问的页在主存时,则形成绝对地址,但不去模拟指令的执行,而用输出转换后的地址来代替一条指令的执行。当访问的页不在主存时,则输出“* 该页页号”,表示产生了一次缺页中断。该模拟程序的算法如图11。 图11 地址转换模拟算法 2、用先进先出(FIFO)页面调度算法处理缺页中断。

数字图像处理实验报告

目录 实验一:数字图像的基本处理操作....................................................................... 错误!未定义书签。:实验目的 .............................................................................................................. 错误!未定义书签。:实验任务和要求..................................................................................................... 错误!未定义书签。:实验步骤和结果..................................................................................................... 错误!未定义书签。:结果分析................................................................................................................. 错误!未定义书签。实验二:图像的灰度变换和直方图变换............................................................... 错误!未定义书签。:实验目的 .............................................................................................................. 错误!未定义书签。:实验任务和要求..................................................................................................... 错误!未定义书签。:实验步骤和结果..................................................................................................... 错误!未定义书签。:结果分析................................................................................................................. 错误!未定义书签。实验三:图像的平滑处理....................................................................................... 错误!未定义书签。:实验目的 .............................................................................................................. 错误!未定义书签。:实验任务和要求..................................................................................................... 错误!未定义书签。:实验步骤和结果..................................................................................................... 错误!未定义书签。:结果分析................................................................................................................. 错误!未定义书签。实验四:图像的锐化处理......................................................................................... 错误!未定义书签。:实验目的 .............................................................................................................. 错误!未定义书签。:实验任务和要求..................................................................................................... 错误!未定义书签。:实验步骤和结果..................................................................................................... 错误!未定义书签。:结果分析................................................................................................................. 错误!未定义书签。

相关文档
最新文档