还剩81页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
目录前言………………………………………………………..2实验一UNIX/Linux操作系统的实际使用………………….3实验二命令解释程序………………………………………..10实验三进程管理……………………………………………..20实验四存储管理……………………………………………..28实验五简单的数据库管理系统设计………………………..35实验六输入/输出管理………..……………………………..60综合实验………………………………………………………65附录……………………………………………………………75参考书目………………………………………………………83前言操作系统是计算机科学与技术及相关专业的一门重要的专业课,是一门实践性很强的技术课程掌握操作系统原理、熟悉操作系统的使用是各层次计算机软硬件__人员必不可少的基本技能然而,困扰操作系统教学的问题是讲授理论原理比较容易,而如何指导学生进行实践则相对较难其结果导致学生不能深刻地理解操作系统的本质,因而也不能在实际中应用所学的操作系统理论知识及操作系统所提供的功能来解决实际问题一般来说,学习操作系统分为以下几个层次1.学习并掌握操作系统的基本概念及原理,了解操作系统的实现机制2.掌握常用操作系统的使用、操作和维护,成为合格的系统___目前最常用的操作系统主要有UNIX、Linux、Windows等等3.掌握操作系统编程技术4.通过分析操作系统源代码,掌握修改、编写操作系统的能力开放源代码的操作系统Linux的出现为我们提供了机遇在操作系统实践教学上,人们作了__的探索美国人A.S.Tanenbaum是位先驱,由他编写的教学操作系统Minix在很长一段时间里较好地解决了这一问题然而,随着计算机系统的体系结构的变化,元器件以及相应软件的飞速发展,早年__出的Minix在很多方面已经不能适应今天的操作系统教学的需要了在当今计算机科学相对发达的国度,人们也已认识到这方面的问题,他们__出适合他们自己教学用的操作系统—0SP、BACI、NACHOS、TOYOS等,其中OSP、BACI是基于裸机的操作实验系统,而NACHOS、TOYOS是基于模拟器的操作实验系统但是,一个全新的、支持基于Intelx86计算机的操作系统教学实验系统至今仍很少国内这方面的研究相对滞后,就已有的几本关于操作系统实验的书籍来看,一个突出的问题便是教学专用实验系统比较少操作系统本身的构造十分复杂,如何在有效的时间内,使学生既能了解其实现原理又能对原理部分进行有效的实践,是操作系统教学一直在探索的内容本实验课程以Linux操作系统为主要平台,从基本原理出发,提供了UNIX/Linux操作系统的使用、命令解释程序、进程管理、存储管理、简单的数据库管理系统的设计、输入/输出管理等6个实验,希望通过这些实验,使学生能对操作系统的基本原理有更深入的了解,为将来从事操作系统方面的研究工作打下一定的基础实验一UNIX/Linux操作系统的实际使用一.实验目的通过本实验熟悉UNIX/Linux操作系统常用命令的操作和使用二.实验内容
1.进入和退出UNIX/Linux操作系统;
2.常用命令的使用catcdchmodcpdffindgrepidlnls等;
3.全屏幕编辑器vi的熟悉使用三.验证实验1.实验要求1)熟悉开机后登录进入系统和退出系统;2)常用命令的操作使用;3)全屏幕编辑器vi的熟悉使用;4)为以后的上机实验作好准备2.实验步骤1)进入和退出UNIX/Linux操作系统1开机后,执行[运行]可通过telnet2进入login usernamepasswordXXXXX...$3退出$logout或exit2)常用命令1cal[-j][-y][月][年]选项说明-j显示西洋旧历计算机系统日历表示-y显示当年日历月用1~12表示月份默认是本月年可以是1~99994位数,默认是本年2cat[选项]文件列表用于显示文件或连接文件例如
①cata.c将文件a.c输出到屏幕上
②cata.cb.cc.c将文件b.c加到a.c后并建立新文件c.c3cd目录名改变当前工作目录4chmod[选项]模式文件列表改变文件模式例如chmod777a.c使文件a.c在各个级别拥有所有权限注UNIX/Linux有3个安全级所有者级、组访问级和其他用户级在这3级中,各有3种权限读、写和执行chmodo-wr,g-wra.c对组级和其他用户级不拥有写权和读权5clear清除屏幕6compress[选项][文件名]项目说明-c将压缩或解压缩的操作结果写到标准输出,不改变文件-C防止文件细分为块,这产生一个输出文件,旧的压缩版本也可以读取-d解压缩文件-f若输出文件存在,则覆盖,不用提示确认同时,把所有文件包括没压缩的变为.Z文件-v在每个文件压缩完后,打印给出输入文件被压缩百分数信息文件名要压缩的文件名称例如
①compressa压缩文件a,并改名为a.Z
②compress-v/*/home/usr/usrl/压缩目录/home/usr/usrl中所有文件,在每个文件压缩后打印压缩信息compress-da.Z将压缩文件释放回原状态7cp[选项]源文件目标文件cp[选项]源文件组目标目录拷贝文件例如
①cpab将文件a拷贝到文件名为b的文件
②cp-vbet*/dd拷贝所有以bet为开头的文件到目录/dd8date显示系统日期和时间9df报告磁盘剩余空问数单位块每块512字节10du[选项]目录或文件名称显示指定目录或文件使用的空间总数例如du–s/usr/bin报告目录/usr/bin使用的总空间,以块-512B为单位11echo[-n][-e]串本命令把传给它的参数在标准输出显示项目说明-n通常,echo使所有输出都由新行开始,本选项可制止这一点-e使串中的如下字符序列的解释成为可能\a警告响铃\b退格\c在行尾,不新起行\f换页\n换行\r回车\t制表符\v垂直制表符\\反斜杠\mm字符的八进制ASCII码是mm串希望输出的字符串例如
①echoHello在标准输出打印Hello
②echo-e“enterYorN\c”提示用户用Y或N回答而不开始新的一行
③echo-e“Canyouhearthis\07”/07代表八进制数,这里八进制数用于使终端振铃12file[选项]文件列表确认文件是否是可执行文件、文本文件和数据文件等例如file/home/aa/检测文件/home/aa,并报告文件类型13find目录列表匹配标准项目说明目录列表希望查询的文件或文件集的目录列表,目录间用空格分隔匹配标准希望查询的文件的匹配标准或说明-name文件告诉find要找什么文件-typex此类型为x的文件,x代表c字符特殊,b块特殊,d目录,p有名管道,|符号连接,s套接文件或f一般文件-sizen匹配所有修改时间比file文件更新的文件例如find-name“letter*”-print/查找以letter为开头的文件,并打印14grep串文件列表在文件中查找模式,当找到时报告例如grep“[hH]ello”aa在文件aa中查找hello或Hello15ln源文件目标文件在两个文件间建立连接16logname报告用户登录到系统上的名字17ls[选项][文件列表]列出文件系统中的文件项目说明-a显示所有文件,包括当前目录和父目录-c按列输出,纵向排列-x按列输出,横向排列-l给出长表长表显示文件的详细内容,如文件类型、权限、连接或目录计数、所有者、组、字节大小、文件的最近修改时间和文件名文件类型有-常规文件d目录b块特殊设备例如磁盘c字符特殊设备例如终端s__灯m共享存储器p有名管道权限有3个串,每串有3个字节,各串分别代表所有者、组和其他的权限,权限如下r读权w写权x执行权-t按最后修改的时间排序,和-l标志一起使用-u按最后访问的时间排序,和-l标志一起使用文件列表用ls要处理的文件列表例如ls-lt/usr/spool/aa给出长表,按最后修改的时间排序18mkdir[-p目录名]目录在文件系统中建立新目录项目说明-p目录名建立所有不存在父目录的目录目录要建立的新目录例如
①mkdirletters建立letters目录
②mkdir-pletters/aletters/b建立目录letters/a和letters/b19more[选项]文件名按页显示文件项目说明-nn是整数,用于建立大小为n行长的窗口,窗口大小是在屏幕上显示多少行-c用more给文件翻页时通过从头清除一行,然后再在最后写下一行的办法写入通常,more清除屏幕,再写一行文件名希望用more显示的文件列表例如
①moreletter显示名为letter的文件
②ls-l/dev|more按页显示/dev目录下的文件20mv[-f][-I]文件1文件2mv[-f][-I]目录1目录2mv[-f][-I]文件列表目录给文件改名,__文件到一个新的目录或给目录改名项目说明-f使mv执行__而不作显示-I交互模式,在覆盖写文件前提示文件1源文件名.文件2目标文件名新文件名目录1源目录名目录2目标目录名新目录名文件列表用空格分开的文件名列表该选项用于保持文件名移到一个新的目录目录目标目录例如mvlettersletter将文件letters改名为letter21passwd[名字]维护用户口令显示或修改用户口令只有系统___可以删除用户口令22pwd显示当前工作的目录路径23rm[选项]文件列表从文件系统中删除文件及整个目录项目说明文件列表希望删除用空格分开的文件,可以包括目录名-r删除文件列表中指定的目录-f指定强行删除模式24rmdir-p目录表删除目录项目说明-p若指定删除目录的父目录为空,则父目录也被删除目录表用空格分开的目录表,要删除的目录必须为空目录25vi文件名vi是全屏幕编辑器vi有两种工作状态命令模式和输入模式注意大小写!a,i,o进入输入模式Esc回到执行命令状态工作途中,可作为取消命令或进入命令状态的控制退出viw文件名写到指定文件名的文件中如无文件名,将编辑缓冲区内容写到磁盘q或ZZ退出vi,不写入磁盘wq写文件到磁盘,然后退出q!退出不存盘u取消上次编辑命令__光标k↑向上j↓向下h←向左l→向右Shifth回第一行Shiftl到末行Shiftm到中间Shiftg到文件最后nShiftg到文件第n行$到行尾^到行首插人命令a在光标后插入i在光标前插入o在光标下一行插入O在光标上一行插入删除命令x删除光标所在的字符X删除光标前面的字符dw删字d$删光标处到行尾dd删除一行替换命令r将光标所在的字符改为后键入的字符R将原来的字符一个一个地用后键入的替换Shiftr替换字符序列cc整行替换查询命令在冒号后/待查字符向前查待查字符向前查n向下继续重复找Shiftn往下找拷贝、截取命令yy或Y拷贝当前行yx拷贝当前光标位置到x位置p将拷贝的文本置于光标后Shiftp将拷贝的文本置于光标前|charyw拖拉y$拉至行尾yy一行拉出26WC[选项]文件列表计算文件中的字符、字或行的数量项目说明文件列表用空格分开的文件名列表-c只计算字符数-w只计算字数-l只计算行数实验二命令解释程序一.实验目的通过本实验熟悉UNIX/Linux操作系统及C语言,熟悉系统调用的编程能力,了解命令解释程序的基本原理和实现方法二.实验内容1.了解命令解释程序的基本原理和实现方法;2.编程实现一个简单的命令解释程序三.验证实验1.实验要求在UNIX/Linux环境下编写一个简单的shell程序,具有接收和解释、执行命令的功能2.参考源代码/*a______shell*//*usecom__ndle__etoexit*/#includeunistd.h#includesys/types.h#includesys/wait.h#includestdlib.h#includesys/stat.h#includefcntl.h#defineBUFFERSIZE80externchar*get_current_dir_namevoid;externchar*getenvconstchar*name;externpid_twaitpidpid_tpidint*statusintoptions;charbuffer[BUFFERSIZE+1];__in{char*path*arg
[10]*input;intli_inputlenis___is_backijkpidstatus;charlc_char;while1{/*initiations*/is___=0;/*redirectionflag*/is_back=0;/*background*//*shellprompt*/path=get_current_dir_name;printf%s$path;/*开始获取输入*/li_inputlen=0;lc_char=getchar;whilelc_char!=\n{ifli_inputlenBUFFERSIZEbuffer[li_inputlen++]=lc_char;lc_char=getchar;}/*命令超长处理*/ifli_inputlen=BUFFERSIZE{printfYourcom__ndistoolong!Pleasere-enteryourcom__nd!\n;li_inputlen=0;/*reset*/continue;}elsebuffer[li_inputlen]=\0;/*加上串结束符号,形成字串*//*将命令从缓存拷贝到input中*/input=char*__llocsizeofchar*li_inputlen+1;strcpyinputbuffer;/*获取命令和参数并保存在arg中*/fori=0j=0k=0;i=li_inputlen;i++{/*管道和重定向单独处理*/ifinput[i]==||input[i]==||input[i]==|{ifinput[i]==|pipelinputli_inputlen;elseredirectinputli_inputlen;is___=1;break;}/*处理空格、TAB和结束符不用处理‘\n,大家如果仔细分析前面的获取输入的程序的话,*不难发现回车符并没有写入buffer*/ifinput[i]==||input[i]==\t||input[i]==\0{ifj==0/*这个条件可以略去连在一起的多个空格或者tab*/continue;else{buffer[j++]=\0;arg[k]=char*__llocsizeofchar*j;/*将指令或参数从缓存拷贝到arg中*/strcpyarg[k]buffer;j=0;/*准备取下一个参数*/k++;}}else{/*如果字串最后是‘,则置后台运行标记为1*/ifinput[i]==input[i+1]==\0{is_back=1;continue;}buffer[j++]=input[i];}}freeinput;/*释放空间*//*如果输入的指令是le__e则退出while,即退出程序*/ifstrcmparg
[0]le__e==0{printfbye-bye\n;break;}ifis___==0{/*非管道、重定向指令*//*在使用xxec执行命令的时候,最后的参数必须是NULL指针,*所以将最后一个参数置成空值*/arg[k]=char*0;/*判断指令arg
[0]是否存在*/ifis_fileexistarg
[0]==-1{printfThiscom__ndisnotfound!\n;fori=0;ik;i++freearg[i];continue;}/*forkasub-pro__sstoruntheexecutionfile*/ifpid=fork==0/*子进程*/execvbufferarg;else/*父进程*/ifis_back==0/*并非后台执行指令*/waitpidpidstatus0;/*释放申请的空间*/fori=0;ik;i++freearg[i];}}}intis_fileexistchar*comm{char*path*p;inti;i=0;/*使用getenv函数来获取系统环境变量,用参数PATH表示获取路径*/path=getenvPATH;p=path;while*p!=\0{/*路径列表使用‘:’来分隔路径*/if*p!=:buffer[i++]=*p;else{buffer[i++]=/;buffer[i]=\0;/*将指令和路径合成,形成pathname,并使用ac__ss函数来判断该文件是否存在*/strcatbuffercomm;ifac__ssbufferF_OK==0/*文件被找到*/return0;else/*继续寻找其它路径*/i=0;}p++;}/*搜索完所有路径,依然没有找到则返回-1*/return-1;}intredirectchar*inintlen{char*argv
[30]*filename
[2];pid_tpid;intijkfd_infd_outis_in=-1is_out=-1num=0;intis_back=0status=0;/*这里是重定向的命令解析过程,其中filename用于存放重定向文件,*is_inis_out分别是输入重定向标记和输出重定向标记*/fori=0j=0k=0;i=len;i++{ifin[i]==||in[i]==\t||in[i]==\0||in[i]==||in[i]=={ifin[i]==||in[i]=={/*重定向指令最多,各出现一次,因此num最大为2,*否则认为命令输入错误*/ifnum3{num++;ifin[i]==is_in=num-1;elseis_out=num-1;/*处理命令和重定向符号相连的情况,比如lsa*/ifj0num==1{buffer[j++]=\0;argv[k]=char*__llocsizeofchar*j;strcpyargv[k]buffer;k++;j=0;}}else{printfThefor__tiserror!\n;return-1;}}ifj==0continue;else{buffer[j++]=\0;/*尚未遇到重定向符号,字符串是命令或参数*/ifnum==0{argv[k]=char*__llocsizeofchar*j;strcpyargv[k]buffer;k++;}/*是重定向后符号的字符串,是文件名*/else{filename[status]=char*__llocsizeofchar*j;strcpyfilename[status++]buffer;}j=0;/*initate*/}}else{ifin[i]==in[i+1]==\0{is_back=1;continue;}buffer[j++]=in[i];}}argv[k]=char*0;ifis_fileexistargv
[0]==-1{printfThiscom__ndisnotfounded!\n;fori=0;ik;i++freeargv[i];return0;}ifpid=fork==0{/*存在输出重定向*/ifis_out!=-1iffd_out=openfilename[is_out]O_WRONLY|O_CREAT|O_TRUNCS_IRUSR|S_IWUSR==-1{printfOpenout%sError\nfilename[is_out];return-1;}/*存在输入重定向*/ifis_in!=-1iffd_in=openfilename[is_in]O_RDONLYS_IRUSR|S_IWUSR==-1{printfOpenin%sError\nfilename[is_out];return-1;}ifis_out!=-1/*使用dup2函数将标准输出重定向到fd_out上,dup2intoldfdintnewfd实现的*是把oldfd所指的文件描述符__到newfd若newfd为一已打开的文件描述词,*则newfd所指的文件会先被关闭,dup2__的文件描述词与原来的文件描述词*共享各种文件状态*/ifdup2fd_outSTDOUT_FILENO==-1{printfRedirectStandardOutError\n;exit1;}ifis_in!=-1ifdup2fd_inSTDIN_FILENO==-1{printfRedirectStandardOutError\n;exit1;}execvbufferargv;}elseifis_back==0/*runontheTOP*/waitpidpidstatus0;fori=0;ik;i++freeargv[i];ifis_in!=-1{freefilename[is_in];closefd_in;}ifis_out!=-1{freefilename[is_out];closefd_out;}return0;}intpipelchar*inputintlen{char*argv
[2]
[30];intijkcountis_back=0;intli_comm=0fd
[2]fpip
[2];charlc_charlc_end
[1];pid_tchild1child2;/*管道的命令解析过程*/fori=0j=0k=0;i=len;i++{ifinput[i]==||input[i]==\t||input[i]==\0||input[i]==|{ifinput[i]==|/*管道符号*/{ifj0{buffer[j++]=\0;/*因为管道连接的是两个指令,所以用二维数组指针来存放命令和参数,*li_comm是表示第几个指令*/argv[li_comm][k]=char*__llocsizeofchar*j;strcpyargv[li_comm][k++]buffer;}argv[li_comm][k++]=char*0;/*遇到管道符,第一个指令完毕,开始准备接受第二个指令*/li_comm++;count=k;k=0;j=0;}ifj==0continue;else{buffer[j++]=\0;argv[li_comm][k]=char*__llocsizeofchar*j;strcpyargv[li_comm][k]buffer;k++;}j=0;/*initate*/}else{ifinput[i]==input[i+1]==\0{is_back=1;continue;}buffer[j++]=input[i];}}argv[li_comm][k++]=char*0;ifis_fileexistargv
[0]
[0]==-1{printfThisfirstcom__ndisnotfound!\n;fori=0;icount;i++freeargv
[0][i];return0;}/*指令解析结束*//*建立管道*/ifpipefd==-1{printfopenpipeerror!\n;return-1;}/*创建第一个子进程执行管道符前的指令,并将输出写到管道*/ifchild1=fork==0{/*关闭读端*/closefd
[0];iffd
[1]!=STDOUT_FILENO{/*将标准输出重定向到管道的写入端,这样该子进程的输出就写入了管道*/ifdup2fd
[1]STDOUT_FILENO==-1{printfRedirectStandardOutError\n;return-1;}/*关闭写入端*/closefd
[1];}execvbufferargv
[0];}else{/*父进程*//*先要等待写入管道的进程结束*/waitpidchild1li_comm0;/*然后我们必须写入一个结束标记,告诉读管道进程数据到这里就完了*/lc_end
[0]=0x1a;writefd
[1]lc_end1;closefd
[1];ifis_fileexistargv
[1]
[0]==-1{printfThiscom__ndisnotfounded!\n;fori=0;ik;i++freeargv
[1][i];return0;}/*创建第二个进程执行管道符后的指令,并从管道读输入流*/ifchild2=fork==0{iffd
[0]!=STDIN_FILENO{/*将标准输入重定向到管道读入端*/ifdup2fd
[0]STDIN_FILENO==-1{printfRedirectStandardInError!\n;return-1;}closefd
[0];}execvbufferargv
[1];}else/*父进程*/ifis_back==0waitpidchild2NULL0;}fori=0;icount;i++freeargv
[0][i];fori=0;ik;i++freeargv
[1][i];return0;}四.设计实验1.实验要求1)利用C语言编写一个微型命令解释程序,接收并解释以下命令dir:列当前目录cop文件1文件2拷贝文件era文件名删除文件dis文件名显示文件内容end:结束并退出2)进行命令合法性检查,若不合法,显示出错信息,等待重新输入;3)命令前后有空格为合法命令2.程序源代码(学生自行设计)实验三进程管理一.实验目的1.加深对进程概念的理解,明确进程和程序的区别;2.进一步认识并发执行的实质;3.分析进程争用资源的现象,学习解决进程互斥的方法
4.了解UNIX/Linux系统中进程通信的基本原理二.实验内容1.阅读Linux的sched.h源代码,加深对进程管理概念的理解;2.阅读Linux的fork.c源代码,分析进程的创建过程;3.进程创建;4.进程控制5.进程通信三.验证实验1.实验要求1进程的创建编写一段程序,使用系统调用fork创建两个子进程当此程序运行时,在系统中有一个父进程和两个子进程活动让每一个进程在屏幕上显示一个字符;父进程显示字符“a”,子进程分别显示字符“b”和“c”试观察记录屏幕上的显示结果,并分析原因2)进程的控制修改已编写的程序,将每个进程的输出由单个字符改为一句话,再观察程序执行时屏幕上出现的现象,并分析其原因如果在程序中使用系统调用lockf来给每个进程加锁,可以实现进程之间的互斥,观察并分析出现的现象2.参考源代码1进程的创建编写一段程序,使用系统调用fork创建两个子进程当此程序运行时,在系统中有一个父进程和两个子进程活动让每一个进程在屏幕上显示一个字符;父进程显示字符“a”,子进程分别显示字符“b”和“c”试观察记录屏幕上的显示结果,并分析原因#includestdio.h__in{intpl,p2;whilep1=fork==-1;ifp1==Oputchar‘b’;else{whilep2=fork==-1;ifp2==Oputchar‘c’;elseputchar‘a’;}}运行结果bca有时会出现bac分析从进程并发执行来看,输出bac,acb等情况都有可能原因fork创建进程所需的时间要多于输出一个字符的时间,因此在主进程创建进程2的同时,进程1就输出了“b”,而进程2和主程序的输出次序是有随机性的,所以会出现上述结果2)进程的控制修改已编写的程序,将每个进程的输出由单个字符改为一句话,再观察程序执行时屏幕上出现的现象,并分析其原因如果在程序中使用系统调用lockf来给每个进程加锁,可以实现进程之间的互斥,观察并分析出现的现象程序1#includestdio.h__in{intp1,p2,i;whilep1=fork==-1;ifp1==0fori=0;i500;i++printf“child%d\n”,i;else{whilep2=fork==-1ifp2==0fori=0;i500;i++printfson%d\n”,ielsefori=0;i500;i++printfdaughter%d\n”,i;}}运行结果child…sonn…daughter...daughter...或child…son...child…son...daughter…等分析由于函数printf输出的字符串之间不会被中断,因此,字符串内部的字符顺序输出时不变但是,由于进程并发执行时的调度顺序和父子进程的抢占处理机问题,输出字符串的顺序和先后随着执行的不同而发生变化这与打印单字符的结果相同程序2#includestdio.h__in{intp1,p2,i;whilep1=fork==-1;ifp1==O{lockf1,1,0;fori=0;i500;i++printf“Child%d\n”,i;lockf1,0,O;}else{whilep2=fork==-1;ifp2==O{lockf1,1,O;fori=0;i500;i++printfson%d\n”,i;lockf1,0,O;}else{lockf1,1,O;fori=O;i500;i++printfdaughter%d\n”,i;lockf1,0,O;}}}运行结果大致与未上锁的输出结果相同,也是随着执行时间不同,输出结果的顺序有所不同分析因为上述程序执行时,不同进程之间不存在共享临界资源其中打印机的互斥性已由操作系统保证问题,所以,加锁与不加锁效果相同
3.一个模拟进程调度程序#includestdio.hstructpcb/*进程控制块结构体*/{charname
[3];/*进程标识符*/charnumber
[3];/*进程优先数*/charstatus
[2];/*进程状态:0-就绪*/structpcb*next;/*指向后一进程的指针*/structpcb*prior;/*指向前一进程的指针*/}stu;structpcb*fir;/*进程链表的头指针*/structpcb*back;/*进程链表的尾指针*/voidenterdeleteprin;charstr
[12]
[3]={a20b100c300d350};__in{fir=back=NULL;/*对进程链表的头尾指针赋初值*/enter0;/*对进程链表赋初值*/for;;{switchmenu{case1:enter1;break;/*插入或初始化*/case2:delete;break;/*删除*/case3:prin;break;/*显示*/case4:exit0;}}}/*主菜单*/menu{charch
[2];intn;printf\t就绪队列操作请选择功能:\n;printf\t
1.插入进程的信息\n;printf\t
2.删除进程的信息\n;printf\t
3.显示进程链表内容\n;printf\t
4.退出\n;do{printf\n\t请按数字选择:;getsch;n=atoich;}whilen0||n4;returnn;}voidenterintq{int__;structpcb*inf*bc;ifq==1{inf=structpcb*__llocsizeofstu;/*开辟新结点*/if!inf{printf\tuseup!\n;return;}inputs\t请输入进程标识符最多两位:inf-name2;inputs\t请输入进程优先数最多两位:inf-number2;inputs\t请输入进程当前状态一位:inf-status1;fir=bcinffir;/*插入新结点*/}else{for__=0;__4;__++/*结点初始化*/{inf=structpcb*__llocsizeofstu;if!inf{printf\tuseup!\n;return;}strcpyinf-namestr[__*3];strcpyinf-numberstr[__*3+1];strcpyinf-statusstr[__*3+2];fir=bcinffir;}}}inputs__scountchar*__*s;intcount;{charq
[3];do{printf__;/*打印提示信息*/getsq;ifstrlenqcountprintf\t太长了!\n;/*输入长度判断*/}whilestrlenqcount;strcpysq;/*把输入内容放入结构中*/}structpcb*bciststructpcb*i;structpcb*st;{structpcb*j*k;ifatoii-status==0/*判断进程状态是否就绪*/{ifback==NULL/*链表为空时的插入*/{i-next=NULL;i-prior=NULL;back=i;returni;}j=st;/*令J指向链表的头*/whilej{ifstrcmpj-namei-name==0/*进程标识符要唯一*/{printf\n\t该进程已存在就绪队列中\n\n;returnst;}j=j-next;}j=st;k=NULL;whilej{ifatoij-numberatoii-number/*判断进程优先数找到要插入的位置*/{k=j;j=j-next;}else{ifj-prior/*判断J是否为头指针*/{j-prior-next=i;/*在链表的中间插入*/i-next=j;i-prior=j-prior;j-prior=i;returnst;}i-next=j;/*在链表的头插入*/i-prior=NULL;j-prior=i;returni;}}k-next=i;/*在链表的尾插入*/i-next=NULL;i-prior=k;back=i;returnst;}printf\n\t该进程不是就绪状态不能插入就绪队列中\n\n;returnst;}voiddelete{structpcb*in;chars
[2];printf\t请输入进程标识符:;getss;in=fir;whilein{ifstrcmpsin-name==0break;/*寻找要删除的进程*/elsein=in-next;}ifin==NULLprintf\t未找到此进程!\n;ifin{/*找到进程*/iffir==in/*该进程为链表头时*/{fir=in-next;iffirfir-prior=NULL;/*该链表删除进程结点后不为空*/elseback=NULL;}else{in-prior-next=in-next;ifin!=back/*该进程不在链表尾*/in-next-prior=in-prior;elseback=in-prior;}freein;/*释放进程空间*/}}voidprin{structpcb*j;j=fir;whilej{/*显示所有进程的信息*/printf\t%sj-name;printf\t%sj-number;printf\t%sj-status;printf\n;j=j-next;}}四.设计实验1.实验要求1编程实现父进程和子进程通过__实现异步合作使用用户自定义__SIGUSRl由父进程发给子进程,SIGUSR2由子进程发给父进程父进程和子进程各自从终端接收一个字符串也可安排别的更有意义的操作,完成后用kill调用发送__接收到__之后,显示对方的进程号及其字符串利用__方式signalSI__HLD,SIG_IDN使父进程不必等待子进程结束,且不产生“ZOMBIE”2使用系统调用pipe建立一条管道线,两个子进程分别向管道写一句话childpro__ss1issendingamessage!childpro__ss2issendingamessage!父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上
2.程序源代码学生自行设计实验四存储管理一.实验目的存储管理的主要功能之一是合理地分配空间请求页式管理是一种常用的虚拟存储管理技术本实验的目的是通过请求页式存储管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法二.实验内容1.应用程序通过系统调用管理空闲内存的程序设计方法;2.请求页式存储管理中页面置换算法的模拟设计三.验证实验1.实验要求1学习用C语言模拟固定分区的分配方法通过本实验了解操作系统用固定分区的方法进行分配的软件__思路,提高软件__能力2阅读源程序,画出程序流程2.参考源代码#includestdio.hstructgdf/*固定分区结构体*/{charnum
[2];/*区号*/charsize
[4];/*大小*/charbegin
[4];/*起址*/charflag
[2];structgdf*next;/*后指针*/structgdf*prior;/*前指针*/}stu;structgdf*fir;/*分区链表的头指针*/structgdf*back;/*分区链表的尾指针*/voidenterturnprin;charstr
[16]
[4]={11620123236136468141241320};__in{fir=back=NULL;/*对分区链表的头尾指针赋初值*/enter;/*对分区链表赋初值*/for;;{switchmenu{case1:inputs;break;/*输入作业大小并处理*/case2:turn;break;/*改变分配状态*/case3:prin;break;/*显示*/case4:exit0;/*退出*/}}}/*主菜单*/menu{charch
[2];intn;printf\n\t固定分区操作请选择功能:\n;printf\t
1.输入作业的大小\n;printf\t
2.改变分区的分配状态\n;printf\t
3.显示分区链表内容\n;printf\t
4.退出\n;do{printf\t请按数字选择:;getsch;n=atoich;}whilen0||n4;returnn;}voidenter{int__;structgdf*inf*bc;for__=0;__4;__++/*结点初始化*/{inf=structgdf*__llocsizeofstu;/*开辟新结点空间*/if!inf{printf\tuseup!\n;return;}strcpyinf-numstr[__*4];strcpyinf-sizestr[__*4+1];strcpyinf-beginstr[__*4+2];strcpyinf-flagstr[__*4+3];fir=bcinffir;}}inputs{charq
[5];structgdf*inf;inf=fir;whileinf/*寻找空闲分区*/{ifatoiinf-flag==0break;inf=inf-next;}/*不存在空闲分区返回*/if!inf{printf\t暂时没有空闲分区.\n;return;}printf\t输入作业大小K:;/*打印提示信息*/getsq;inf=fir;whileinf/*寻找符合条件的空闲分区找到则返回*/{ifatoiqatoiinf-sizeatoiinf-flag==0{strcpyinf-flag1;printf\t作业已分配在%s区.\ninf-num;return;}inf=inf-next;}printf\t空闲分区不够大请选择另一个较小的作业.\n;}voidturn{charq
[5]q1
[5];structgdf*inf;printf\t输入分区1-4:;/*打印提示信息*/getsq;printf\t输入分配状态0-1:;getsq1;inf=fir;whileinf{ifatoiinf-num==atoiq/*寻找符合条件分区*/{strcpyinf-flagq1;/*改变分区状态*/printf\t%s分区已成功改变分区状态.\ninf-num;return;}inf=inf-next;}printf\t该分区不存在.\n;return;}voidprin/*显示*/{structgdf*j;j=fir;printf\t区号;printf\t大小;printf\t起址;printf\t标志\n;whilej{/*显示固定分区的信息*/printf\t%sj-num;printf\t%sj-size;printf\t%sj-begin;printf\t%sj-flag;printf\n;j=j-next;}}structgdf*bciststructgdf*i;structgdf*st;{structgdf*k;ifback==NULL{i-next=NULL;i-prior=NULL;back=i;returni;}k=back;k-next=i;i-next=NULL;i-prior=k;back=i;returnst;}/*固定分区操作请选择功能:
1.输入作业的大小
2.改变分区的分配状态
3.显示分区链表内容
4.退出请按数字选择:3区号大小起址标志11620123236136468141241320请按数字选择:1输入作业大小K:150空闲分区不够大请选择另一个较小的作业.请按数字选择:1输入作业大小K:120作业已分配在4区.请按数字选择:1暂时没有空闲分区.请按数字选择:3区号大小起址标志11620123236136468141241321请按数字选择:2输入分区1-4:2输入分配状态0-1:02分区已成功改变分区状态.请按数字选择:3区号大小起址标志11620123236036468141241321*/四.设计实验1.实验要求1通过随机数产生一个指令序列,共320条指令指令的地址按下述原则生成150%的指令是顺序执行的;225%的指令是均匀分布在前地址部分;325%的指令是均匀分布在后地址部分具体的实施方法是1在[O,319]的指令地址之间随机选取一起点m;2顺序执行一条指令,即执行地址为m+1的指令;3在前地址[O,m+1]中随机选取一条指令并执行,该指令的地址为m’;4顺序执行一条指令,其地址为m’+1;5在后地址[m’+2,319]中随机选取一条指令并执行;6重复上述步骤1~5,直到执行320次指令2将指令序列变换成为页地址流设1页面大小为1K;2用户内存容量为4页到32页;3用户虚存容量为32K在用户虚存中,按每K存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为第0条~第9条指令为第0页对应虚存地址为[O,9];第10条~第19条指令为第1页对应虚存地址为[10,19];..第310条~第319条指令为第31页对应虚存地址为[310,319]按以上方式,用户指令可组成32页3计算并输出下述各种算法在不同内存容量下的命中率1先进先出的算法FIFO;2最近最少使用算法LRR;3最佳淘汰算法OPT先淘汰最不常用的页地址;4最少访问页面算法LFR;5最近最不经常使用算法NUR其中3和4为选择内容命中率=1-页面失效次数/页地址流长度在本实验中,页地址流长度为320,页面失效次数为每次访问相应指令时,该指令所对应的页不在内存的次数关于随机数产生办法,UNIX/Linux系统提供函数srand和rand,分别进行初始化和产生随机数例如srand;语句可初始化一个随机数;a
[0]=10*rand/32767*319+1;a
[1]=10*rand/32767*a
[0];上述语句可用来产生a
[0]与a[l]中的随机数2.实验提示本实验的程序设计基本上按照实验内容进行即首先用srand和rand函数定义和产生指令序列,然后将指令序列变换成相应的页地址流,并针对不同的算法计算出相应的命中率相关定义如下1数据结构1页面类型typedefstruct{intpn,pfn,counter,time;}pl_type;其中pn为页号,pfn为面号,也即内存物理页面号,counter为一个周期内访问该页面次数,time为访问时间2页面控制结构pfc_struct{intpn,pfn;structpfc-struct*next;};typedefstructpfc_structpfc_type;pfc_typepfc[total_vp],*freepf_head,*busypf_head;pfc_type*busypf_tail;其中pfc[total_vp]定义用户进程虚页控制结构,*freepf_head为空页面头的指针,*busypf_head为忙页面头的指针,*busypf_tail为忙页面尾的指针2函数定义1voidinitialize初始化函数,给每个相关的页面赋值2voidFIFO计算使用FIFO算法时的命中率3voidLRU计算使用LRU算法时的命中率4voidOPT计算使用OPT算法时的命中率5voidLFU计算使用LFU算法时的命中率6voidNUR计算使用NUR算法时的命中率3变量定义1inta[tatal_instruction]指令流数据组2intpage[total_instruction]每条指令所属页号3intoffset[total_instruction]每页装入10条指令后取模运算页号偏移值4inttotal_pf用户进程的内存页面数5intdiseffect页面失效次数
3.程序源代码学生自行设计实验五简单的数据库管理系统设计一.实验目的通过一个简单的数据库管理系统的设计,加深理解文件系统的内部功能及实现方法二.实验内容1.了解文件系统的基本原理及设计方法;2.设计一个简单的数据库管理系统三.验证实验1.实验要求设计实现一个简单的模拟文件管理系统,包括目录文件、普通文件、i结点和存储区,具体要求如下1程序初始化时应构造如下图所示的目录结构2在此模拟文件管理系统中可以实现的操作有a.改变目录cd目录名,工作目录转移到指定的目录下目录不存在时,给出错误信息b.创建文件edit文件名,创建一个指定名字的新文件,即在目录中增加一项,不考虑文件的内容对于重名文件给出错误信息c.删除文件del文件名,当没有用户使用指定文件时,将其删除文件不存在时给出错误信息d.显示目录dir目录名,显示指定目录下的全部文件和第一级子目录,如果没有指定目录名,则显示当前目录下的相应内容e.创建目录md目录名,在指定路径下创建指定的目录,如没有指定路径,则在当前目录下创建指定的目录对于重名目录给出错误信息f.删除目录rd目录名,删除指定目录及其下的全部文件和子目录如果指定目录为空,可直接删除,否则给出用户提示是否删除其他说明a.目录名和文件名都支持全路径名和相对路径名b.文件名由目录结构中各级文件名分量排列构成,各分量间用“/”隔开c.输入exit命令可退出此模拟文件管理系统2.设计方案
(1)程序的总体框架及函数之间的调用关系图函数之间的关系如下图所示每个函数的说明如下__in主函数CdComd改变目录功能处理EditComd创建文件功能处理DelComd删除文件功能处理RdComd删除目录功能处理Dircomd显示目录功能处理Mdcomd创建目录功能处理Init初始化文件树Par_______nd接受输入的命令并将其分解成操作名和路径文件名ExecuteCom__nd执行命令,根据参数Paral,调用相应的功能处理模块;若输入命令有误,则报错FindPath查找参数ph所指向的路径FindFileName从参数para2找到要建立或者删除的子目录、文件名,并调用查找路径子函数把指针指向其父亲结点CreateFileNode:创建结点Getlnput缓冲区安全输入子函数,如果输入超过缓冲区长度,则截取前[缓冲区长度一1]位,最后一位补“\0”CheckCom__nd命令检查GetDir获取当前目录名Trim对命令进行格式处理,即去掉空格等
(2)主要数据结构及算法整个文件系统采用二叉树型存储结构,如下图所示每一个结点的结构如下structFileNode{charfilename[FILENAME_LEN];/*文件名/目录名*/intisdir;/*目录文件识别标志*/inti_nlink;/*文件的链接数*/intadr;/*文件的地址structFileNode*parent,*child;/*指向父亲的指针和指向左孩子的指针*/structFileNode*sibling_prev,*sibling_next;/*指向前一个兄弟的指针和指向/*后一个兄弟的指针*/};
(3)流程图本程序__包含一个主函数和16个子函数,这里仅对其中的9个函数用流程图来进行详细说明a.__in主函数,见下图b.FindFileName子函数获取文件或目录名,并调用查找路径子函数把指针指向其父亲结点,见下图c.Par_______nd分解命令子函数,见下图d.CdComd cd改变目录功能处理子函数,见下图e.EditComd edit创建文件功能处理子函数,见下图f.DelComd:del删除文件功能处理子函数,见下图g.RdComd:rd删除目录功能处理子函数,见下图h.DirComd:dir显示目录功能处理子函数,见下图3.参考源代码#includestdio.h#includestring.h#includectype.h#include__lloc.h#defineFILENAME_LEN21#defineINPUT_LEN81#defineCOM__ND_LEN11//结点结构structFileNode{charfilename[FILENAME_LEN];//文件名/目录名intisdir;//目录文件识别标志inti_nlink;//文件的链接数intadr;//文件的地址structFileNode*parent*child;//指向父亲的指针和指向左孩子的指针structFileNode*sibling_prev*sibling_next;//指向前一个兄弟的指针和指向//后一个兄弟的指针.};voidInit;//初始化文件树intPar_______nd;//接受输入的命令并把其分解成操作名和路径文件名voidExecuteCom__nd;//执行命令intcdComd;//处理cd命令inteditComd;//处理edit命令intdelComd;//处理del命令intrdComd;//处理rd命令intdirComd;//处理dir命令intmdComd;//处理md命令intFindPathchar*ph;//寻找参数ph所指向的路径//从参数Para2中找到要建立或删除的文件、目录名,并把指针指向其父亲结点intFindFilenamecharPara2[];structFileNode*CreateFileNodecharfilename[]intisdirinti_nlink;//创建结点intGetInputchar*bufferunsignedintbuffer_len;//获取输入intCheckCom__nd;//命令检查intGetDirintbeginchar*pathchar*curDir;//获取路径voidTrimchar*str;structFileNode*cp*tp*root*upper;charpath[INPUT_LEN-COM__ND_LEN];//记录当前走过的路径charcurpath[INPUT_LEN-COM__ND_LEN]Para1[COM__ND_LEN]Para2[INPUT_LEN-COM__ND_LEN]tmppath[INPUT_LEN-COM__ND_LEN];charfilename[FILENAME_LEN]dirname[FILENAME_LEN]tmp;intij;//主函数int__in{Init;//初始化文件树while1{ifPar_______nd//分解命令ExecuteCom__nd;//执行命令}}//执行命令子函数voidExecuteCom__nd{intsign;//根据参数Para1调用相应的功能处理模块ifstrcmpPara1cd==0sign=cdComd;//cd命令elseifstrcmpPara1edit==0sign=editComd;//edit命令elseifstrcmpPara1del==0sign=delComd;//del命令elseifstrcmpPara1dir==0sign=dirComd;//dir命令elseifstrcmpPara1md==0sign=mdComd;//md命令elseifstrcmpPara1rd==0sign=rdComd;//rd命令elseifstrcmpPara1exit==0exit0;//exit命令elseprintf命令错误请重试\n;//命令输入不正确,报错}//创建结点structFileNode*CreateFileNodecharfilename[]intisdirinti_nlink{//申请结点空间structFileNode*node=structFileNode*__llocsizeofstructFileNode;//相应内容赋初值strcpynode-filenamefilename;node-isdir=isdir;node-i_nlink=i_nlink;node-parent=NULL;node-child=NULL;node-sibling_prev=NULL;node-sibling_next=NULL;returnnode;}//初始化文件树voidInit{structFileNode*binNode*usrNode*unixNode*etcNode*libNode*userNode*binNode2*liuNode*sunNode*ftiNode;strcpypath/;//根目录写入当前路径//创建文件树的结点binNode=CreateFileNodebin10;usrNode=CreateFileNodeusr10;unixNode=CreateFileNodeunix00;etcNode=CreateFileNodeetc10;libNode=CreateFileNodelib10;userNode=CreateFileNodeuser10;binNode2=CreateFileNodebin10;liuNode=CreateFileNodeliu10;sunNode=CreateFileNodesun10;ftiNode=CreateFileNodefti10;cp=tp=root=CreateFileNode/10;//结点相应内容赋值root-parent=NULL;root-child=binNode;root-sibling_prev=root-sibling_next=NULL;binNode-parent=root;binNode-child=NULL;binNode-sibling_prev=NULL;binNode-sibling_next=usrNode;usrNode-parent=NULL;usrNode-child=libNode;usrNode-sibling_prev=binNode;usrNode-sibling_next=unixNode;unixNode-parent=NULL;unixNode-child=NULL;unixNode-sibling_prev=usrNode;unixNode-sibling_next=etcNode;etcNode-parent=NULL;etcNode-child=NULL;etcNode-sibling_prev=unixNode;etcNode-sibling_next=NULL;libNode-parent=usrNode;libNode-child=liuNode;libNode-sibling_prev=NULL;libNode-sibling_next=userNode;userNode-parent=NULL;userNode-child=NULL;userNode-sibling_prev=libNode;userNode-sibling_next=binNode2;binNode2-parent=NULL;binNode2-child=NULL;binNode2-sibling_prev=userNode;binNode2-sibling_next=NULL;liuNode-parent=libNode;liuNode-child=NULL;liuNode-sibling_prev=NULL;liuNode-sibling_next=sunNode;sunNode-parent=NULL;sunNode-child=NULL;sunNode-sibling_prev=liuNode;sunNode-sibling_next=ftiNode;ftiNode-parent=NULL;ftiNode-child=NULL;ftiNode-sibling_prev=sunNode;ftiNode-sibling_next=NULL;}//获取文件或目录名,并把指针指向其父亲结点intFindFilenamecharPara2[]{i=strlenPara2-1;j=0;whilePara2[i]!=/i=0{filename[j]=Para2[i];i--;j++;}filename[j]=\0;//获得逆序的文件或目录名,存入filename中ifi0Para2[i+1]=\0;elsePara2[i]=\0;j--;//filename逆转,获得正确的文件或目录名fori=0;istrlenfilename/2;i++j--{tmp=filename[i];filename[i]=filename[j];filename[j]=tmp;}//查找路径ifstrlenPara20{intsign=FindPathPara2;ifsign==0return0;}return1;}//缓冲区安全输入子函数//如果输入超过buffer_len,则截取前buffer_len-1长度的输入,//buffer_len处字符用/0代替intGetInputchar*bufferunsignedintbuffer_len{intcount=0;whilecountbuffer_len{ifbuffer[count]=getchar==10{buffer[count]=\0;returncount;}count++;}whilegetchar!=10;buffer[buffer_len-1]=\0;return-1;}//分解命令子函数intPar_______nd{charInputs[INPUT_LEN];inti=0j=0k=0ch;printf%spath;//获取输入ifGetInputInputsINPUT_LEN==-1{printf输入行太长\n;return0;}Para1
[0]=Para2
[0]=\0;//获取参数Para1,即操作名whileInputs[i]!=Inputs[i]!=\0iCOM__ND_LEN-1{Para1[i]=Inputs[i];i++;}//whilePara1[i]=\0;//输入命令太长ifi==COM__ND_LEN-1return1;//获取参数2,即路径文件名ifInputs[i]!=\0{whileInputs[i]==iINPUT_LEN-1i++;j=0;whileInputs[i]!=\0iINPUT_LEN-1{Para2[j]=Inputs[i];i++;j++;}Para2[j]=\0;}TrimPara1;TrimPara2;//将操作名全部转换成小写字母fork=0;kstrlenPara1;k++{ch=tolowerintPara1[k];Para1[k]=ch;}return1;}//cd功能处理子函数intcdComd{if!CheckCom__nd//命令检查return0;ifstrcmpPara
2..==0{//对cd..命令的处理inti;whilecp-sibling_prevcp=cp-sibling_prev;//找到这一层最左边的结点ifcp-parent{cp=cp-parent;//找到父亲结点}else{return0;}//对当前路径进行相应处理i=strlenpath;whilepath[i]!=/i0i--;ifi!=0path[i]=\0;elsepath[i+1]=\0;}else{FindPathPara2;//查找路径}return1;}//命令格式处理子函数voidTrimchar*str{intbeginend;char*tmp;begin=0;end=strlenstr;//找到字符串第一个非空格的位置whilestr[begin]==str[begin]!=\0begin++;//去除字符串尾部空格whilestr[--end]==;str[end+1]=\0;//除去空格ifbeginend{tmp=char*__llocsizeofchar*end-begin+2;strcpytmpstr[begin];strcpystrtmp;freetmp;}}//获取当前目录名子函数intGetDirintbeginchar*pathchar*curDir{inti=0;intlen=strlenpath;while!path[begin]==\\||path[begin]==/beginlen{curDir[i++]=path[begin++];}curDir[i]=\0;TrimcurDir;returnbegin+1;}//查找路径子函数intFindPathchar*ph{structFileNode*tp*temp;charoldpath[INPUT_LEN-COM__ND_LEN];inti=0;intsign=1;ifstrcmpph/==0{//ph是根目录cp=root;strcpypath/;return1;}temp=cp;strcpyoldpathpath;//保存原路径和指针ifph
[0]==/{//指针指向根目录的左孩子cp=root-child;i++;//滤过/strcpypath/;}else{ifcp!=NULLcp!=rootstrcatpath/;ifcpcp-child{ifcp-isdircp=cp-child;//指针指向当前目录的左孩子else{printf路径错误!\n;return0;}}}whilei=strlenphcp//继续查找指定路径,如遇到文件则报错{intj=0;ifph[i]==/cp-child{i++;//略过/ifcp-isdircp=cp-child;//继续查找下级目录else{printf路径错误!\n;return0;}strcatpath/;}//curpath记录当前要找的路径名whileph[i]!=/i=strlenph{curpath[j]=ph[i];i++;j++;}curpath[j]=\0;whilestrcmpcp-filenamecurpath!=0||cp-isdir!=1cp-sibling_next!=NULL{cp=cp-sibling_next;}ifstrcmpcp-filenamecurpath==0{ifcp-isdir==0{strcpypatholdpath;cp=temp;printf是文件不是目录.\n;return0;}strcatpathcp-filename;}ifstrcmpcp-filenamecurpath!=0||cp==NULL{strcpypatholdpath;cp=temp;printf输入路径错误\n;return0;}}return1;}//创建文件子函数inteditComd{chartmp;structFileNode*temp=CreateFileNode00;intsign;structFileNode*tp;//路径不能为空ifstrlenPara2==0{printf\n命令格式有错误.\n;return0;}//长度检查ifstrlenPara250{printf\n文件名过长\n;return0;}//格式检查if!isalphaPara2
[0]||Para2
[0]==_||Para2
[0]==\0||Para2
[0]==/{printf文件名格式有错!\n;/*文件首字母可以为字母或数字或_或/或回车*/return0;}//获取文件名sign=FindFilenamePara2;ifsign==0return0;ifcp-isdir!=1//如当前指针指向的是文件,则报错{printfyoucannoteditafileinunderafile!\n;return0;}//创建文件结点,并插入到指定目录下tp=CreateFileNode10;strcpytp-filenamefilename;tp-isdir=0;tp-i_nlink=0;ifcp-child==NULL{tp-parent=cp;tp-child=NULL;cp-child=tp;tp-sibling_prev=NULL;tp-sibling_next=NULL;}else{temp=cp;//用temp找到新结点插入处temp=temp-child;whiletemp-sibling_next//findthelastsibingnode{temp=temp-sibling_next;ifstrcmptemp-filenamefilename==0temp-isdir==0{printf此文件名已存在\n;//重名报错return0;}}//找到了最后一个结点temp-sibling_next=tp;tp-parent=NULL;tp-child=NULL;tp-sibling_prev=temp;tp-sibling_next=NULL;}return1;}//创建目录子函数intmdComd{chartmp;intsign;structFileNode*temp*tp;temp=CreateFileNode10;//参数不能为空ifstrlenPara2==0{printf\n命令格式有错误.\n;return0;}//长度检查ifstrlenPara250{printf\n目录名过长\n;return0;}//格式检查if!isalphaPara2
[0]||Para2
[0]==_||Para2
[0]==\0||Para2
[0]==/{printf目录名格式有错!\n;/*目录首字母可以为字母或数字或_或/或回车*/return0;}//获取目录名sign=FindFilenamePara2;ifsign==0return0;//若当前指针指向的是文件,则报错ifcp-isdir!=1{printfyoucannot__keadirectoryinunderafile!\n;return0;}//创建目录结点,并插入到指定目录下tp=CreateFileNodefilename10;ifcp-child==NULL{tp-parent=cp;tp-child=NULL;cp-child=tp;tp-sibling_prev=NULL;tp-sibling_next=NULL;}else{temp=cp;//用temp找到新结点插入处temp=temp-child;whiletemp-sibling_next//findthelastsibingnode{temp=temp-sibling_next;ifstrcmptemp-filenamefilename==0temp-isdir==1{printf此文件名已存在\n;//重名报错return0;}}//找到了最后一个结点temp-sibling_next=tp;tp-parent=NULL;tp-child=NULL;tp-sibling_prev=temp;tp-sibling_next=NULL;}return1;}//删除文件子函数intdelComd{chartmp;intsign;structFileNode*temp;//参数不能为空ifstrlenPara2==0{printf\n命令格式有错误.\n;return0;}//获取文件名sign=FindFilenamePara2;ifsign==0return0;//用temp指向要删除的结点ifcp-child{temp=cp-child;whiletemp-sibling_nextstrcmptemp-filenamefilename!=0||temp-isdir!=0temp=temp-sibling_next;ifstrcmptemp-filenamefilename!=0{printf不存在该文件!\n;return0;}}else{printf不存在该文件!\n;return0;}//要删除的不能是目录iftemp-isdir!=0{printfERROR!该命令只能删除文件不可删除目录!\n;return0;}//如仍有用户使用该文件,则不能删除iftemp-i_nlink!=0{printf还有用户共享了该文件不能删除!\n;return0;}//删除工作iftemp-parent==NULL//不是第一个孩子{temp-sibling_prev-sibling_next=temp-sibling_next;iftemp-sibling_next//处理是最后一个兄弟的情况temp-sibling_next-sibling_prev=temp-sibling_prev;temp-sibling_prev=temp-sibling_next=NULL;}//ifelse//第一个孩子{iftemp-sibling_next//处理是最后一个兄弟的情况temp-sibling_next-parent=temp-parent;temp-parent-child=temp-sibling_next;}//elsefreetemp;return1;}//命令检查子函数intCheckCom__nd{ifstrlenPara2==0{printf命令语法不正确\n;return0;}return1;}//删除目录子函数intrdComd{chartmp;structFileNode*temp;charcmd
[2];//命令检查if!CheckCom__ndreturn0;//获取目录名if!FindFilenamePara2return0;//用temp指向要删除的结点ifcp-child{temp=cp-child;whiletemp-sibling_nextstrcmptemp-filenamefilename!=0||temp-isdir!=1temp=temp-sibling_next;ifstrcmptemp-filenamefilename!=0{printf不存在该目录!\n;return0;}}else{printf不存在该目录!\n;return0;}//要删除的不能是文件iftemp-isdir!=1{printfERROR!该命令只能删除目录不可删除文件!\n;return0;}//若要删除的目录不为空,则提示用户是否删除iftemp-child{printf\n该目录不为空您确定要删除吗Y/N\n;GetInputcmd2;ifstrcmpcmdn==0||strcmpcmdN==0return0;}//删除工作iftemp-parent==NULL//不是第一个孩子{temp-sibling_prev-sibling_next=temp-sibling_next;iftemp-sibling_next//处理是最后一个兄弟的情况temp-sibling_next-sibling_prev=temp-sibling_prev;temp-sibling_prev=temp-sibling_next=NULL;}//ifelse//第一个孩子{iftemp-sibling_next//处理是最后一个兄弟的情况temp-sibling_next-parent=temp-parent;temp-parent-child=temp-sibling_next;}//elsefreetemp;return1;}//显示目录子函数intdirComd{ifstrlenPara20{intsign=FindPathPara2;//查找路径ifsign==0{return0;}else{printf\n%spath;}}ifcp!=rootprintfDIR%s\n..;ifcp-child==NULL{return0;//指定目录为空}tp=cp;//指定目录不为空,显示其所有子目录及文件名tp=tp-child;whiletp{iftp-isdirprintfDIR%s\ntp-filename;elseprintfFILE%s\ntp-filename;tp=tp-sibling_next;}}四.设计实验1.实验要求设计一个简单的数据库管理系统,实现以下功能:1创建数据库文件,数据库文件以文本文件的形式存放;2往数据库文件中添加记录;3删除数据库文件中的记录;4显示数据库文件中的记录;5关闭数据库文件
2.程序源代码学生自行设计实验六输入/输出管理一.实验目的理解Linux操作系统的设备管理机制,了解Linux操作系统中的设备驱动程序的组成,编写简单的字符设备和块设备驱动程序二.实验内容1.了解和学习Linux内部设备的控制和管理方法;2.编写简单的字符设备和块设备驱动程序三.验证实验1.实验要求1)了解和学习Linux内部设备的控制和管理方法;2)学习如何实现Linux下对机器内部扬声器的编程内部扬声器是控制台的一部分,所以它对应的设备文件为/dev/console变量KIOCSOUND在头文件/usr/include/linux/kd.h中声明,使用ioctl函数可以控制扬声器的发声,使用规则为ioctlfd,KIOCSOUND,inttone;fd为文件设备号,tone是音频值当tone为0时,终止发声但是,这里和我们平常认为的音频是不同的由于计算机主板定时器的时钟频率为
1.19MHz,所以要进行正确的发声,必须进行如下的转换扬声器音频值=1190000/期望的音频值扬声器发声时间的长短通过函数usleepunsignedlongusec来控制,它在头文件/usr/include/unistd.h中定义,让程序睡眠usec微秒2.参考源代码//让扬声器按指定的长度和音频发声#includefcntl.h#includestdio.h#includestdlib.h#includestring.h#includeunistd.h#includesys/ioctl.h#includesys/types.h#includelinux/kd.h//设定默认值#defineDEFAULT_FREQ440//设定一个合适的频率#defineDEFAULT_LENGTH200//200微秒,发声的长度以微秒为单位#defineDEFAULT_REPS1//默认不重复发声#defineDEFAULT_DELAY100//同样以微秒为单位//定义一个结构,存储所需的数据typedefstruct{intfreq;//期望输出的频率,单位为Hzintlength;//发声长度,以微秒为单位intreps;//重复的次数intdelay;//两次发声间隔,以微秒为单位}beep_parms_t;//打印帮助信息并退出voidusage_bailconstchar*executable_name{printfUsage:\n\t%s[-ffrequency][-llength][-rreps][-ddelay]\nexecutable_name;exit1;}//分析运行参数,各项意义如下//-f以Hz为单位的频率值//-l以毫秒为单位的发声时长//-r重复次数//-d以毫秒为单位的间歇时长voidparse_com__nd_linechar**argvbeep_parms_t*result{char*arg0=*argv++;while*argv{if!strcmp*argv-f{//频率intfreq=atoi*++argv;iffreq=0||freq_____{fprintfstderrBadparameter:frequencymustbefroml.._____\n;exit1;}else{result-freq=freq;argv++;}}elseif!strcmp*argv-l{//发声的时间长度intlength=atoi*++argv;iflength0{fprintfstderrBadparameter:lengthmustbe=0\n;exit1;}else{result-length=length;argv++;}}elseif!strcmp*argv-r{//重复次数intreps=atoi*++argv;ifreps0{fprintfstderrBadparameter repsmustbe=0\n;exit1;}else{result-reps=reps;argv++;}}elseif!strcmp*argv-d{//延时intdelay=atoi*++argv;ifdelay0{fprintfstderrBadparameter:delaymustbe=0\n;exit1;}else{result-delay=delay;argv++;}}else{fprintfstderrBadparameter%s\n*argv;usage_bailarg0;}}}int__inintar__char**argv{intconsole_fd;inti;//循环计数器//设发声参数为默认值beep_parms_tparms={DEFAULT_FREQDEFAULT_LENGTHDEFAULT_REPSDEFAULT_DELAY};//分析参数,可能的话更新发声参数parse_com__nd_lineargvparms;//打开控制台,失败则结束程序ifconsole_fd=open/dev/consoleO_WRONLY==-1{fprintfstderrFailedtoopenconsole.\n;perroropen;exit1;}//真正开始让扬声器发声fori=0;iparms.reps;i++{int__gical_fairy_number=1190000/parms.freq;ioctlconsole_fdKIOCSOUND__gical_fairy_number;//开始发声usleep1000*parms.length;//等待…ioctlconsole_fdKIOCSOUND0;//停止发声usleep1000*parms.delay;//等待…}//重复播放returnEXIT_SUC__SS;}四.设计实验1.实验要求1)编写一个简单的字符设备驱动程序,再编写一个测试程序来测试你所编写的字符设备驱动程序2)编写一个简单的块设备驱动程序2.程序源代码学生自行设计综合实验Linux文件系统设计一.实验目的通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现二.实验内容为Linux系统设计一个简单的二级文件系统,要求做到以下几点1.可以实现下列几条命令login用户登录dir列文件目录create创建文件delete删除文件open打开文件close关闭文件read读文件write写文件2.列目录时要列出文件名、物理地址、保护码和文件长度;3.源文件可以进行读写保护三.实验要求1.首先应确定文件系统的数据结构主目录、子目录及活动文件等主目录和子目录都以文件的形式存放于磁盘,便于查找和修改2.用户创建的文件,可以编号存储于磁盘上,并以编号作为物理地址,在目录中进行登记四.实验指导1.设计思想本文件系统采用两级目录,其中第一级对应于用户账号,第二级对应于用户账号下的文件另外,为了简单本文件系统未考虑文件共享、文件系统安全以及管道文件与设备文件等特殊内容2.主要数据结构1i节点structinode{structinode*i_forw;structinode*i_back;chari_flag;unsignedinti_ino;/*磁盘i节点标号*/unsignedinti_count;/*引用计数*/unsignedshortdi_number;/*关联文件数,当为0时,则删除该文件*/unsignedshortdi_mode;/*存取权限*/unsignedshortdi_uid;/*磁盘i节点用户id*/unsignedshortdi_gid;/*磁盘i节点组id*/unsignedintdi_addr[NADDR];/*物理块号*/}2磁盘i节点structdinode{unsignedshortdi_number;/*关联文件数*/unsignedshortdi_mode;/*存取权限*/unsignedshortdi_uid;unsignedshortdi_gid;unsignedlongdi_size;/*文件大小*/unsignedintdi_addr[NADDR];/*物理块号*/3目录项结构structdirect{chard_name[DIRSIZ];/*目录名*/unsignedintd_ino;/*目录号*/}4超级块structfilsys{unsignedshorts_isize;/*i节点块块数*/unsignedlongs_fsize;/*数据块块数*/unsignedints_nfree;/*空闲块块数*/unsignedshorts_pfree;/*空闲块指针*/unsignedints_free[NICFREE];/*空闲块堆栈*/unsignedints_ninode;/*空闲i节点数*/unsignedshorts_pinode;/*空闲i节点指针*/unsignedints_inode[NICINOD];/*空闲i节点数组*/unsignedints_rinode;/*铭记i节点*/chars_fmod;/*超级块修改标志*/};5用户__structpwd{unsignedshortP_uid;unsignedshortP_gid;charpassword[PWOSIZ];};6目录structdir{structdirectdirect[DIRNUM];intsize;};7查找内存i节点的hash表structhinode{structinode*i_forw;};8系统打开表structfile{charf_flag;/*文件操作标志*/unsignedintf_count;/*引用计数*/structinodef_inode;/*指向内存i节点*/unsignedlongf_off;/*读/写指针*/};9用户打开表structuser{unsignedshortu_default_mode;unsignedshortu_uid;/*用户标志*/unsignedshortu_gid;/*用户组标志*/unsignedshortu_ofile[NOFILE];/*用户打开表*/};3.主要函数1i节点内容获取函数iget2i节点内容释放函数iput3目录创建函数mkdir4目录搜索函数namei5磁盘块分配函数balloc6磁盘块释放函数bfree7分配i节点区函数ialloc8释放i节点区函数ifree9搜索当前目录下文件的函数iname10访问控制函数ac__ss11显示目录和文件用函数dir12改变当前目录用函数chdir13打开文件函数open14创建文件函数create15读文件用函数read16写文件用函数write17用户登录函数login18用户退出函数logout19文件系统格式化函数for__t20进入文件系统函数install21关闭文件函数close22退出文件系统函数halt23文件删除函数delete4.主程序说明Begin对磁盘进行格式化调用install,进入文件系统调用dir,显示当前目录调用login,用户注册调用mkdir和chdir创建目录调用creat,创建文件0分配缓冲区写文件0关闭文件0和释放缓冲调用mkdir和chdir创建子目录调用creat,创建文件1分配缓冲区写文件1关闭文件1和释放缓冲调用chdir将当前目录移到上一级调用creat,创建文件2分配缓冲区调用write,写文件2关闭文件2和释放缓冲调用delete,删除文件0调用creat,创建文件3为文件3分配缓冲区调用write,写文件3关闭文件3并释放缓冲区调用open,打开文件2为文件2分配缓冲写文件3后关闭文件3释放缓冲用户退出logout关闭haltEnd五.程序设计参考
1.编程管理文件__kefile本文件系统程序用__kefile编程管理工具进行管理,其内容如下filsys__in.0igetput.0iallfre.0ballfre.0name.0ac__ss.0log.0close.0creat.0delete.0dir.0open.0rdwt.0for__t.0install.0halt.0cc—0filsys__in.0igetput.0iallfre.0ballfre.0name.0ac__ss.0log.0close.0creat.0delete.0dir.0open.0rdwt.0for__t.0install.0halt.0__in.0__in.cfilesys.hcc-c__in.cigetput.0igetput.cfilesys.hcc-cigetput.ciallfre.0iallfre.cfilesys.hcc-ciallfre.cballfre.0hallfre.cfilesys.hcc-cballfre.cname.o name.cfilesys.hcc-cname.cac__ss.o ac__ss.cfilesys.hcc-cac__ss.clog.0log.cfilesys.hcc-clog.cclose.o close.cfilesys.hcc-cclose.ccreat.o creat.cfilesys.hcc-ccreat.cdelete.O:delete.cfilesys.hcc-cdelete.cdir.O:dir.cfilesys.hcc-cdir.copen.o open.cfilesys.hcc-copen.crdwt.O rdwt.cfilesys.hcc-crdwt.cfor__t.O for__t.cfilesys.hcc-cfor__t.cinstall.O install.cfilesys.hcc-cinstall.chalt.O halt.ccc-chalt.c2.头文件filesys.h头文件filesys.h用来定义本文件系统中所使用的各种数据结构和常数符号#defineBLOCKSIZ512#defineSYSOPENFILE40#defineDIRNUM128#defineDlRSIZ14#definePWDSIZ12#definePWDNUM32#defineNOFILE20#defineNADDR10#defineNHINO128/*mustbepowerof2*/#defineUSERNUM10#defineDINODESIZ32/*filsys*/#defineDINODEBLK32#defineFILEBLK512#defineNlCFREE50#defineNICINOD50#defineDINODESTART2*BLOCKSIZ#defineDATASTART2+DINODEBLK*BLOCKSIZ/*di_mode*/#define___MPTY00000#defineDIFILE01000#defineDIDIR02000#defineUDIREAD00001#defineUDIWRITE00002#defineU___XICUTE00004#defineGDIREAD00010#defineGDIWRITE00020#defineG___XICUTE00040#defineODIREAD00100#defineODIWRITE00200#defineO___XICUTE00400#defineREAD1#defineWRITE2#defineEXICUTE3#defineDEFAULTMODE00777/*i_flag*/#defineIUPDATE00002/*s_fmod*/#defineSUPDATE00001/*f_flag*/#defineFREAD00001#defineFWRITE00002#defineFAPPEND00004/*error*/#defineDISKFULL65535/*fseekorigin*/#defineSEEK_SET0/*文件系统数据结构*/structinode{structinode*i_forw;structinode*I_back;charpassword[PWDSIZ];}structdir{structdirectdirect[DIRNUM];intsize;/*当前目录大小*/};structhinode{structinode*i_forw;};structfile{charf_flag;/*文件操作标志*/.unsignedintf_count;/*引用计数*/structinode*f_inode;/*指向内存i节点*/unsignedlongf_off;/*read/writecharacterpointer*/};structuser{unsignedshortu_default_mode;unsignedshortu_uid;unsignedshortu_gid;unsignedshortu_ofile[NOFIIE];/*用户打开文件表*/}/*以下为全局变量*/externstructhinodehinode[NHINO];externstructdirdir;/*当前目录在内存中全部读入*/externstructfilesys_ofile[SYSOPENFILE];externstructfilsysfilsys;/*内存中的超级块*/externstructpwdpwd[PWDNUM];externstructuseruser[USERNUM];externFILE*fd;externstructinode*cur_path_inode;externintuser_id;/*proptypeofthesubroutionusedinthefilesystem*/externstructinode*iget;externiput;externunsignedintballoc;externbfree;externstructinode*ialloc;externifree;externunsignedintnamei;externunsignedshortiname;externunsignedintac__ss;externdir;externmkdir;externchdir;externunsignedshortopen;externcreat;externunsignedintread;externunsignedintwrite;externintlogin;externlogout;externinstall;externfor__t;externclose;externhalt;
3.主程序__in文件名__in.c主程序__in.c用来测试文件系统的各种设计功能#include“stdio.H”#include“filesys.h”structhinodehinode[NHINO];structdirdir;structfilesys_ofile[SYSOPENFILE];structfilsysfilsys;structpwdpwd[PWDNUM];structuseruser[USERNUM];FILE*fd;structinode*cur_path_inode;intuser_id;__in{unsignedshortab_fdl,ab_fd2,ab_fd3,ab_fd4;unsignedshortbhy_fdl;char*buf;printf“\nD0youwanttofor__tthedisk\n”;ifgetchar==’y’printf“\nFor__twilleraseallcontextonthedisk\nAreYouSure!!\n”;ifgetehar==’y’for__t;install;dir;login2118,”abcd”;user_id=0;mkdir“a2118”;chdir“a2118”;wj_fdl=creat2118,ab_fileO.c”01777;buf=char*__llocBLOCKSIZ*6+5;writeab_fdl,buf,BLOCKSIZ*6+5;closeuser_id,ab_fdl;freebuf;mkdir“subdir”;chdir“subdir”;wj_fd2=creat2118,file1.c”,01777;buf=char*__llocBLOCKSIZ*4+20;writeab_fd2,buf,BLOCKSIZ*4+20;closeuser_id,ab_fd2;freebuf;chdir”..”;ab_fd3=creat2118,”file2.c”,01777;buf=char*__llocBLOCKSIZ*10+255;writeab_fd3,buf,BLOCKSIZ*3+255;closeab_fd3;freebuf;deleteab_file0.c”;ab_fd4=ereat2118,ab_file3.c”,01777;buf=char*__llocBLOCKSIZ*8+300;writeab_fd4,buf,BLOCKSIZ*8+300;closeab_fd4;freebuf;ab_fd3=open2118,ab_file2.c”,FAPPEND;buf=char*__llocBLOCKSIZ*3+100;writeab_fd3,buf,BLOCKSIZ*3+100;closeab_fd3;freebuf;dir;chdir”..”;logout;halt;}附录《操作系统》教学大纲大纲说明课程代码总学时64学时(讲课48学时,实验16学时)总学分4课程类别必修适用专业计算机科学与技术,信息管理与信息系统预修要求C程序设计、数据结构、计算机组成原理,汇编语言程序设计课程的性质、目的、任务操作系统是计算机系统的基本组成部分,它在整个计算机系统软件中占据核心地位操作系统是计算机科学的基本课程之一,它涉及到对各种资源(包括硬件资源和软件资源)的有效管理,又为高层软件的运行提供了良好的工作环境,起到承上启下,纵横贯通的作用通过本课程的学习,应使学生掌握操作系统的基本功能以及实现这些功能的相应算法,培养、训练学生从计算机应用的角度来分析问题和解决问题,并用合适的算法来表示问题的求解,为应用软件特别是非数值应用软件的__和计算机系统软件的进一步__和利用打下良好的基础课程教学的基本要求掌握操作系统的基本功能以及实现这些功能的相应算法,培养、训练学生从计算机应用的角度来分析问题和解决问题,并用合适的算法来表示问题的求解了解主流操作系统的关键技术及其发展动态,掌握主流操作系统的实际应用,更好地适应实际工作的需要该课程采用教师授课和学生自学相结合的教学方法,以教师授课为主,结合理论知识,通过实验来论证,加深理解在授课过程中可采用多媒体课件进行操作演示,帮助学生进一步理解和掌握大纲正文第一章操作系统概述学时4学时(讲课4学时)本章讲授要点计算机系统的软件和硬件组成,操作系统的基本概念,操作系统的技术发展过程,操作系统的特征,操作系统的分类,操作系统的功能,研究操作系统的几种观点重点操作系统的基本概念,操作系统的技术发展过程难点操作系统的特征第一节操作系统概观第二节操作系统的概念第三节操作系统的功能第四节操作系统的发展第五节操作系统分类第六节研究操作系统的几种观点第二章操作系统的硬件环境学时2学时(讲课2学时)本章讲授要点操作系统运行的硬件环境组成,__处理器,存储系统,中断机制,I/O系统,时钟以及时钟队列重点操作系统运行的硬件环境组成,__处理器,存储系统难点中断机制,I/O系统,时钟以及时钟队列第一节__处理器第二节存储系统第三节缓冲技术第四节中断技术第五节I/O技术第六节时钟第三章进程管理学时14学时(讲课10学时,实验4学时)本章讲授要点多道程序设计,并发程序,进程的基本概念,进程控制块,进程状态及状态转换,进程控制,进程同步机制,进程通信,进程调度,Linux的进程管理重点进程的基本概念,进程控制块,进程状态及状态转换,Linux的进程管理难点进程通信,进程调度,Linux的进程管理第一节多道程序设计第二节进程第三节进程同步与互斥第四节进程通信第五节进程调度第六节系统内核第七节Linux的进程管理第四章存储管理学时14学时(讲课10学时,实验4学时)本章讲授要点存储体系,存储管理的目的和任务,分区存储管理方案,段式存储管理方案,页式存储管理方案,段页式存储管理方案,虚拟存储技术,Linux的存储管理重点页式存储管理方案,虚拟存储技术,Linux的存储管理难点页式存储管理方案,虚拟存储技术,Linux的存储管理第一节概述第二节分区管理第三节页式存储管理第四节段式存储管理第五节段页式存储管理第六节覆盖技术与交换技术第七节虚拟存储管理第八节Linux的存储管理第五章文件管理学时14学时(讲课10学时,实验4学时)本章讲授要点文件目录,文件控制块、文件目录结构,文件的逻辑结构与存取方式,自由空间的管理,文件系统的实现,文件系统的安全,Linux的文件系统重点文件目录,文件控制块,文件目录结构,文件的逻辑结构与存取方式,自由空间的管理,Linux的文件系统难点文件的逻辑结构与存取方式,自由空间的管理,Linux的文件系统第一节概述第二节文件目录第三节文件系统的使用第四节文件的逻辑结构与存取方式第五节存储介质第六节文件系统的实现第七节文件系统的安全第八节文件系统的性能问题第九节文件系统的可靠性第八节Linux的文件系统第六章设备管理学时14学时(讲课10学时,实验4学时)本章讲授要点I/O软件的组成,I/O硬件的特点,I/O设备分配,I/O设备有关技术,Linux的I/O设备管理重点I/O软件的组成,I/O设备分配,I/O设备有关技术,Linux的I/O设备管理难点I/O设备有关技术,Linux的I/O设备管理第一节概述第二节I/O软件的组成第三节I/O硬件的特点第四节I/O设备分配第五节I/O设备有关技术第六节网络I/O设备第七节几种典型I/O设备第八节Linux的I/O设备管理第七章死锁学时2学时(讲课2学时)本章讲授要点死锁基本概念,死锁预防,死锁避免,死锁检测与解除重点死锁基本概念,死锁预防难点死锁避免,死锁检测与解除第一节死锁基本概念第二节死锁预防第三节死锁避免第四节死锁检测与解除第五节资源分配图本课程对学生自学的要求部分章节要求学生自学课时数分配表章节名称总课时讲课实验第一章操作系统概论44第二章操作系统的硬件环境22第三章进程管理14104第四章存储管理14104第五章文件管理14104第六章设备管理14104第七章死锁22小计644816考核方式与要求考核方式采用闭卷笔试,可以给出不超过30%的平时成绩,并综合期末考试,最后给出总评成绩作为该课程的成绩推荐教材与参考书目
1、孟庆昌,操作系统教程—Linux实例分析,西安电子科技大学出版社
2、陈向群,杨芙清,操作系统教程,北京大学出版社
3、徐德民,操作系统原理Linux篇,国防工业出版社
4、AbrahamSilberschatz等,操作系统概念(第六版影印版),高等教育出版社,JohnWileySonsInc
5、张尧学等,计算机操作系统教程(第2版),清华大学出版社
6、李善平等,Linux内核
2.4版源代码分析大全,机械工业出版社
7、怀石工作室,Linux上的C编程,中国电力出版社
8、许社村,RedHatLinux9中文版入门与进阶,清华大学出版社
9、张红光等,UNIX操作系统教程,机械工业出版社《操作系统》实验大纲一.总则
1.本大纲的适用范围1本大纲相关的课程名称及课程属性课程名称操作系统课程属性学科基础课程2本大纲的适用范围计算机科学与技术专业,信息管理与信息系统专业3实验总时数16学时
2.本大纲的实验目的和要求加深对操作系统原理的理解,具体掌握某一种操作系统(本实验采用Linux操作系统)的实现方法,增强学生对操作系统内核和工作原理的理解
3.本大纲的所需实验设备普通微机,Linux操作系统二.实验项目及学时安排
1.实验项目一UNIX/Linux操作系统的实际使用1实验类型验证性实验2实验开设属性必开实验3学时数4学时4实验目的通过本实验熟悉Linux操作系统常用命令的操作和使用5实验要求熟悉开机后登录进入系统和退出系统;常用命令的操作使用;全屏幕编辑器vi的熟悉使用;为以后的上机实验作好准备
2.实验项目二命令解释程序1实验类型设计性实验2实验开设属性必开实验3学时数4学时4实验目的通过本实验熟悉Linux操作系统及C语言,熟悉系统调用的编程能力,程序中允许使用库函数5实验要求a.利用C语言编写一个微型命令解释程序,接收并解释以下命令dir列当前文件目录cop文件1文件2拷贝文件era文件名删除文件typ文件名显示文件内容end:结束并退出b.进行命令合法性检查,若不合法,显示出错信息,等待重新输入
3.实验项目三进程管理1实验类型设计性实验2实验开设属性必开实验3学时数4学时4)实验目的加深对进程概念的理解,明确进程和程序的区别;进一步认识并发执行的实质;分析进程争用资源的现象,学习解决进程互斥的方法5实验要求a.阅读Linux的sched.h源代码,加深对进程管理概念的理解;b.阅读Linux的fork.c源代码,分析进程的创建过程;c.进程的创建编写一段程序,使用系统调用fork创建两个子进程当此程序运行时,在系统中有一个父进程和两个子进程活动让每一个进程在屏幕上显示一个字符父进程显示字符“a”;子进程分别显示字符“b”和字符“c”试观察记录屏幕上的显示结果,并分析原因d.进程的控制修改已编写的程序,将每个进程输出一个字符改为每个进程输出一句话,观察程序执行时屏幕上出现的现象,并分析原因如果在程序中使用系统调用lockf来给每一个进程加锁,可以实现进程之间的互斥,观察并分析出现的现象
4.实验项目四存储管理1实验类型设计性实验2实验开设属性必开实验3学时数4学时4)实验目的存储管理的主要功能之一是合理地分配空间请求页式管理是一种常用的虚拟存储管理技术本实验的目的是通过请求页式存储管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法通过请求页式存储管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法5)实验要求a.通过随机数产生一个指令序列,共320条指令指令的地址按下述原则生成
①50%的指令是顺序执行的;
②25%的指令是均匀分布在前地址部分;
③25%的指令是均匀分布在后地址部分具体的实施方法是
①在[O,319]的指令地址之间随机选取一起点m;
②顺序执行一条指令,即执行地址为m+1的指令;
③在前地址[O,m+1]中随机选取一条指令并执行,该指令的地址为m’;
④顺序执行一条指令,其地址为m’+1;
⑤在后地址[m’+2,319]中随机选取一条指令并执行;
⑧重复上述步骤
①~
⑤,直到执行320次指令b.将指令序列变换成为页地址流设
①页面大小为1K;
②用户内存容量为4页到32页;
③用户虚存容量为32K在用户虚存中,按每K存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为第0条~第9条指令为第0页对应虚存地址为[O,9];第10条~第19条指令为第1页对应虚存地址为[10,19];...第310条~第319条指令为第31页对应虚存地址为[310,319]按以上方式,用户指令可组成32页c.计算并输出下述各种算法在不同内存容量下的命中率
①先进先出的算法FIFO;
②最近最少使用算法LRR;
③最佳淘汰算法OPT先淘汰最不常用的页地址;
④最少访问页面算法LFR;
⑤最近最不经常使用算法NUR其中
③和
④为选择内容命中率=1-页面失效次数/页地址流长度在本实验中,页地址流长度为320,页面失效次数为每次访问相应指令时,该指令所对应的页不在内存的次数关于随机数产生办法,Linux或UNIX系统提供函数srand和rand,分别进行初始化和产生随机数例如srand;语句可初始化一个随机数;a
[0]=10*rand/32767*319+1;a
[1]=10*rand/32767*a
[0];上述语句可用来产生a
[0]与a[l]中的随机数
5.实验项目五简单的数据库管理系统设计1实验类型设计性实验2实验开设属性选开实验3学时数4学时4实验目的通过一个简单的数据库管理系统的设计,加深理解文件系统的内部功能及实现方法5)实验要求设计一个简单的数据库管理系统,实现以下功能:
1.创建数据库文件,数据库文件以文本文件的形式存放;
2.往数据库文件中添加记录,往数据库文件中添加记录时,可以指定添加位置;
3.删除数据库文件中的记录,删除数据库文件中的记录时,可以指定删除范围;
4.显示数据库文件中的记录,显示数据库文件中的记录时,可以指定显示范围
5.关闭数据库文件
6.实验项目六输入/输出管理1实验类型设计性实验2实验开设属性选开实验3学时数4学时4实验目的理解Linux操作系统的设备管理机制,了解Linux操作系统中的设备驱动程序的组成,编写简单的字符设备和块设备驱动程序5实验要求了解和学习Linux内部设备的控制和管理方法;学习如何实现Linux下对机器内部扬声器的编程了解Linux操作系统中的设备驱动程序的组成,编写简单的字符设备和块设备驱动程序参考书目1.张尧学编著.计算机操作系统教程(第2版)习题解答与实验指导.北京清华大学出版社,20042.吴企渊,梁燕编著.计算机操作系统(第2版).北京清华大学出版社,
20033.徐洪等.操作系统实验指导—基于Linux内核.北京清华大学出版社,
20044.赵敏哲.64位Linux操作系统与应用实例.北京机械工业出版社,20015.任爱华.操作系统__与提高.北京清华大学出版社,20046.周苏.操作系统原理实验.北京科学出版社,20037.李林英等.操作系统原理UNIX篇习题与实验指导.北京清华大学出版社,
20048.http://os.zju.edu.cnhttp://os.zju.edu.cn.2005PAGE20。