实验设计与指导(学生用).doc_第1页
实验设计与指导(学生用).doc_第2页
实验设计与指导(学生用).doc_第3页
实验设计与指导(学生用).doc_第4页
实验设计与指导(学生用).doc_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

计算机操作系统实验设计与指导计算机与信息学院2011-2012学年度第一学期目 录实验一 Linux入门3实验二 Linux进程控制6实验三 进程间通信10实验四 页面置换算法模拟17实验五 简单多用户文件系统22实验一 Linux入门【实验目的】1、了解LINUX运行环境的命令及使用格式。2、熟悉LINUX的常用基本命令。3、练习并掌握LINUX下C语言程序的编写、编译、调试和运行方法。【实验内容】1、熟悉LINUX的常用基本命令如logout/exit、adduser、deluser、ls、cd、pwd、mkdir、rmdir、rm、cp、mv、cat、man等。2、用vi编写一个简单的显示“hello word!”的程序,用gcc编译并观察编译后的结果,运行生成的可执行文件。【实验过程】记录自己这实验课上具体的操作内容、过程【实验小结】实验收获、实验过程中遇到的问题已经心得【实验指导】一、 介绍虚拟机安装以及使用方法1、 虚拟软件 Vmware是一个虚拟软件,本质就是利用软件技术,在母机hosts中虚拟出另外一台或者几台子机guests,而在子机中,可以随意进行任何操作,并且都不会影响主机Vmware中创建的OS实际上是在硬盘上创建了一个文件夹,该OS中的所有东西都保存在这个文件夹中的文件里面。比如:BIOS、硬盘、配置文件等。Vmware虚拟的是一台“真正”的机器,主机所支持的OS一般Vmware也都支持。虚拟机内存直接使用主机的内存,一般要分配至少占主机一半的内存给虚拟机用。以根用户登录:用户名:root 密码:redhat2、 设置共享Windows: d:lin_shareLinux: /mnt/hgfs/sharefolders/二、 常用基本命令的使用用root账号(超级用户)注册,口令为redhat(注意大小写)。注册成功出现#号(超级用户系统提示符,普通用户的系统提示符为$)。命令格式:命令 选项 处理对象注意:(1)命令一般是小写字串。注意大小写有别 (2)选项通常以减号(-)再加上一个或数个字符表示,用来选择一个命令的不同操作 (3)同一行可有数个命令,命令间应以分号隔开 (4)命令后加上&可使该命令后台(background)执行1 logout、exit、halt、reboot 一组用户注销以及关机和重启命令在linux里,不能直接用电源按钮开关,也不能用reset按钮重启,这对系统,尤其是硬盘有比较大的影响2 练习使用命令ls(注意Linux命令区分大小写。)i. 使用ls 查看当前目录内容;使用ls 查看指定目录内容,如/目录,/etc目录ii. 使用ls all 查看当前目录内容;使用dir 查看当前目录内容3 使用cd改变当前目录cd . 回到上层目录 ;cd / 回到根目录4 pwd 显示当前路径 5 建立目录mkdirmkdir 目录名 ; mkdir /home/s2001/newdir 6 删除目录:rmdir;7 复制文件cp: 如 cp 文件名1 文件名28 移动文件或目录: mv 9 删除文件 rm10 显示文件内容:more (分页显示); 11 显示文件:cat 文件名 建立文件:cat 文件名,ctrl+d结束输入添加新用户、修改文件属性12 添加新用户(在root下,按默认值回答)adduser 用户名;如adduser s2001 ; 以新用户登录到系统13 修改用户口令 passwd14 查看相关命令的帮助:man 命令名显示一屏后,按键将显示更多与命令有关的用户手册内容;按返回命令行提示符。15 显示当前系统中已注册的用户信息:who16 显示当前注册的用户信息:whoami 三、使用编辑器vi 编辑文件vi是在linux 上被广泛使用的中英文编辑软件。vi是visual editor的缩写,是linux提供给用户的一个窗口化编辑环境。进入vi,直接执行vi编辑程序即可。显示器出现vi的编辑窗口,同时vi会将文件复制一份至缓冲区(buffer)。vi先对缓冲区的文件进行编辑,保留在磁盘中的文件则不变。编辑完成后,使用者可决定是否要取代原来旧有的文件。vi提供二种工作模式:输入模式(insert mode)和命令模式(command mode)。使用者进入vi后,即处在命令模式下,此刻键入的任何字符皆被视为命令,可进行删除、修改、存盘等操作。要输入信息,应转换到输入模式。1. 进入linux的文本模式之后,在命令行键入vi filename.c 然后回车。下面作一些简单的解释:首先vi命令是打开vi编辑器。后面的filename.c是用户即将编辑的c文件名字,注意扩展名字是.c;当然,vi编辑器功能很强,可以用它来编辑其它格式的文件,比如汇编文件,其扩展名字是.s;也可以直接用vi打开一个新的未命名的文件,当保存的时候再给它命名,只是这样做不很方便。2. 最基本的命令I :当进入刚打开的文件时,不能写入信息,这时按一下键盘上的I键(insert),插入的意思,就可以进入编辑模式了。如下图所示: 3. a与i是相同的用法4. 当文件编辑完后,需要保存退出,这时需要经过以下几个步骤:1)按一下键盘上的Esc 键;2)键入冒号(:),紧跟在冒号后面是wq(意思是保存并退出)。如果不想保存退出,则在第二步键入冒号之后,键入!q(不带w,机尾部保存)。如下图所示:在输入模式下,按ESC可切换到命令模式。命令模式下,可选用下列指令离开vi:q!离开vi,并放弃刚在缓冲区内编辑的内容:wq将缓冲区内的资料写入磁盘中,并离开vi:ZZ同wq:x同wq:w将缓冲区内的资料写入磁盘中,但并不离开vi:q离开vi,若文件被修改过,则要被要求确认是否放弃修改的内容,此指令可与:w配合使用5. 退出vi编辑器的编辑模式之后,要对刚才编写的程序进行编译。四、GNU C编译器LINUX上可用的C编译器是GNU C编译器,它建立在自由软件基金会编程许可证的基础上,因此可以自由发布。LINUX 上的GNU C编译器(GCC)是一个全功能的ANCI C兼容编译器,而一般UNIX(如SCO UNIX)用的编译器是CC。下面介绍GCC和一些GCC编译器最常用的选项。通常后跟一些选项和文件名来使用GCC编译器。GCC命令的基本用法如下: gcc options filenames命令行选项指定的编译过程中的具体操作当不用任何选项编译一个程序时,GCC将建立(假定编译成功)一个名为a.out的可执行文件。例如, gcc test.c编译成功后,当前目录下就产生了一个a.out文件。也可用-o选项来为即将产生的可执行文件指定一个文件名来代替a.out。例如:gcc o count count.c此时得到的可执行文件就不再是a.out,而是count。6. 编译的命令是:gcc filename.c -o outputfilename,其中gcc是c的编译器。参数:filename.c 是刚才编辑的c 文件(当然也可以是以前编写好的c文件);后面中括号里面的参数是可选的,它是一个输出文件。如果不选,默认的输出文件是a.out ,选了之后输出文件就是outputfilename.out7. 最后一步是运行程序,执行文件 格式: ./可执行文件名方法如下:./outputfilename.out实验二 Linux进程控制【实验目的】 1) 加深对进程概念的理解,明确进程和程序的区别;2) 进一步认识并发执行的概念,区别顺序执行和并发执行;3) 掌握进程创建的方法4) 熟悉进程的睡眠,同步和撤销等进程控制方法5) 分析进程争用临界资源的现象,学习解决进程互斥的方法; 【实验内容】1) 编写一段程序,使用系统调用fork()创建两个子进程。各进程显示不同的信息,如父进程显示字符“a”,子进程分别显示字符“b”和“c”。多次运行观察显示结果,并分析产生这种执行效果的原因。2) 修改已编写的程序,将每个进程输出一个字符改为每个进程输出一句话,在观察程序执行时屏幕出现的现象,并分析原因3) 一个父进程创建一个子进程,子进程通过exec系统调用执行另一个文件。各自的代码中显示不同的信息,从其运行结果可看出两个进程并发执行的效果。4) 利用wait()来控制进程执行顺序,并用exit()来终止进程执行,分析wait( )是如何实现进程同步的5) 选作:如果在程序中使用调用lockf()来给每一个子进程加锁,可以实现进程之间的互斥,观察并分析出现的现象。【实验要求】1) 仔细观察实验中的各种现象及出现的问题。分析产生各种现象的原因。寻找解决问题的办法。2) 实验报告中给出程序的主要语句并且加入相应的注释即可,程序太多时不需要给出程序的全部语句,给出输出的结果及对各种现象的分析意见。【实验指导】Linux系统中,进程是进程映像的执行过程,也就是正在执行的进程实体。它由三部分组成: 用户级上、下文。主要成分是用户程序; 寄存器上、下文。由CPU中的一些寄存器的内容组成,如PC,PSW,SP及通用寄存器等; 系统级上、下文。包括OS为管理进程所用的信息,有静态和动态之分。一、所涉及的系统调用1fork( ) 创建一个新进程。系统调用格式: Int pid=fork( )fork( )返回值意义如下:0:在子进程中,pid变量保存的fork( )返回值为0,表示当前进程是子进程。0:在父进程中,pid变量保存的fork( )返回值为子进程的id值(进程唯一标识符)。-1:创建失败。如果fork( )调用成功,它向父进程返回子进程的PID,并向子进程返回0,即fork( )被调用了一次,但返回了两次。在linux下一个进程在内存里有三部分的数据,即:代码段、堆栈段和数据段。堆栈段:存放的就是子程序的返回地址、子程序的参数以及程序的局部变量。数据段:则存放程序的全局变量,常数以及动态数据分配的数据空间。一个程序一旦调用fork()函数,系统就为一个新的进程准备了前述三个段,首先,系统让新的进程与旧的进程使用同一个代码,因为它们的程序是相同的,对于数据段和堆栈段,系统则复制一份给新的进程,这样,父进程的所有数据都可以留给子进程,但是子进程一旦开始运行,虽然它继承了父进程的一切数据,但实际上数据都已经分开,相互之间不再有影响了,也就是说,它们之间不再共享任何数据了。2getpid( )取得目前进程的识别码(进程ID),许多程序利用取到的此值来建立临时文件,以避免临时文件相同带来的问题。系统调用格式: int getpid()例如:#include main() printf(“pid=%dn”,getpid();3getppid( )取得目前进程的父进程识别码。系统调用格式: int getppid() 例如:#include main() printf(“My parents pid=%dn”,getppid();4exec( )系列fork( )只是将父进程的用户级上下文拷贝到新进程中,而exec( )系列可以将一个可执行的二进制文件覆盖在新进程的用户级上下文的存储空间上,以更改新进程的用户级上下文。exec( )系列中的系统调用都完成相同的功能,它们把一个新程序装入内存,来改变调用进程的执行代码,从而形成新进程。如果exec( )调用成功,调用进程将被覆盖,然后从新程序的入口开始执行,这样就产生了一个新进程,新进程的进程标识符id 与调用进程相同。exec( )没有建立一个与调用进程并发的子进程,而是用新进程取代了原来进程。所以exec( )调用成功后,没有任何数据返回,这与fork( )不同。exec( )系列系统调用在UNIX系统库unistd.h中,共有execl、execlp、execle、execv、execvp五个,其基本功能相同,只是以不同的方式来给出参数。一种是直接给出参数的指针,如:int execl(path,arg0,arg1,.argn,0);char *path,*arg0,*arg1,.,*argn;另一种是给出指向参数表的指针,如:int execv(path,argv);char *path,*argv ;具体使用可参考有关书。5exec( )和fork( )联合使用系统调用exec和fork( )联合使用能为程序开发提供有力支持。用fork( )建立子进程,然后在子进程中使用exec( ),这样就实现了父进程与一个与它完全不同子进程的并发执行。一般,wait、exec联合使用的模型为:int status; .if (fork( )= =0) .; execl(.); .; 6wait( )等待子进程运行结束。如果子进程没有完成,父进程一直等待。wait( )将调用进程挂起,直至其子进程因暂停或终止而发来软中断信号为止。如果在wait( )前已有子进程暂停或终止,则调用进程做适当处理后便返回。系统调用格式:int wait(status)int *status;其中,status是用户空间的地址。7exit( )终止进程的执行。系统调用格式: void exit(status) int status;其中,status是返回给父进程的一个整数,以备查考。8lockf(files,function,size)用作锁定文件的某些段或者整个文件。本函数的头文件为#include unistd.h参数定义:int lockf(files,function,size)int files,function;long size;其中:files是文件描述符;function是锁定和解锁:1表示锁定,0表示解锁。size是锁定或解锁的字节数,为0,表示从文件的当前位置到文件尾。二、 进程创建程序实示例: #include main() int p; while(p=fork()= -1); if(p=0) printf(“This is a child process.”);/*在子进程中*/ else Printf(“This is a parent process.”);/*在父进程中*/ 实验三 进程间通信【实验目的】1) 了解什么是信号以及熟悉LINUX系统中进程之间软中断通信的基本原理2) 了解什么是管道以及熟悉LINUX支持的管道通信方式3) 了解什么是消息以及熟悉消息传送的机理【实验内容】任务一:进程的软中断通讯任务:编写一段程序,使其现实进程的软中断通信。 修改参考程序,使用系统调用fork()创建子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按DEL或ctrl+c键);当捕捉到中断信号后,父进程用系统调用Kill()向子进程发出信号,子进程捕捉到信号后输出下列信息后终止: stop 子进程ID by signal 16(或17)! Child Processl is Killed! 父进程等待子进程终止后,输出如下的信息后终止 stop 父进程ID by signal 2! Parent Process is Killed!要求:分析利用软中断通信实现进程同步的机理,signal()放在程序的不同位置处,记录输出结果并分析原因。任务二:进程的管道通信任务:编写程序实现进程的管道通信。用系统调用pipe( )建立一管道,二个子进程P1和P2分别向管道各写一句话: Child 1 is sending a message! Child 2 is sending a message!父进程从管道中读出二个来自子进程的信息并显示(要求先接收P1,后P2)。要求: 用管道进行通讯,实质上是一个多生产者单消费者的问题,必须考虑其中都有哪些同步和互斥,同时向管道输入端写的字节数必须和从输出端读的字节数一致,若不一致,则会出现什么问题。任务三:消息通信任务:使用系统调用msgget( ),msgsnd( ),msgrev( ),及msgctl( )编制一长度为k的消息发送(client.c)和接收(server.c)的程序。要求:二个程序分别编辑、编译为client与server。执行:./server&ipcs -q./client。观察上面的程序,记录实验结果,说明控制消息队列系统调用msgctl () 在此起什么作用?(选作:为了便于操作和观察结果,用一个程序为“引子”,先后fork()两个进程,server和client 进行通信。)【实验要求】1) 写实验报告时不需要把所有的实验内容都抄上去,简单给出任务即可。2) 主要结合程序,给出实验结果并分析原因3) 程序体中必须加入详细的注释信息4) 实验报告的结尾应给出简洁的总结(或实验小结)【实验指导】一、所涉及到的系统调用1 kill( )系统调用格式int kill(pid,sig)参数定义int pid,sig;其中,pid是一个或一组进程的标识符,参数sig是要发送的软中断信号。(1)pid0时,核心将信号发送给进程pid。(2)pid=0时,核心将信号发送给与发送进程同组的所有进程。(3)pid=-1时,核心将信号发送给所有用户标识符真正等于发送进程的有效用户标识号的进程。2 signal( )预置对信号的处理方式,允许调用进程控制软中断信号。系统调用格式signal(sig,function)头文件为 #include 参数定义signal(sig,function)int sig;void (*func) ( )其中sig用于指定信号的类型,sig为0则表示没有收到任何信号,常用如下表:值名 字说 明01SIGHUP挂起(hangup)02SIGINT中断,当用户从键盘按c键或break键时03SIGQUIT退出,当用户从键盘按quit键时16SIGUSR1用户自定义信号117SIGUSR2用户自定义信号218SIGCLD某个子进程死 function:在该进程中的一个函数地址,在核心返回用户态时,它以软中断信号的序号作为参数调用该函数,对除了信号SIGKILL,SIGTRAP和SIGPWR以外的信号,核心自动地重新设置软中断信号处理程序的值为SIG_DFL,一个进程不能捕获SIGKILL信号。function 的解释如下:(1)function=1时,进程对sig类信号不予理睬,亦即屏蔽了该类信号;(2)function=0时,缺省值,进程在收到sig信号后应终止自己;(3)function为非0,非1类整数时,function的值即作为信号处理程序的指针。3 pipe( )建立一无名管道。系统调用格式 pipe(filedes)参数定义int pipe(filedes);int filedes2;其中,filedes1是写入端,filedes0是读出端。该函数使用头文件如下:#include #inlcude #include 4 read( ) 系统调用格式 read(fd,buf,nbyte) 功能:从fd所指示的文件中读出nbyte个字节的数据,并将它们送至由指针buf所指示的缓冲区中。如该文件被加锁,等待,直到锁打开为止。 参数定义 int read(fd,buf,nbyte); int fd; char *buf; unsigned nbyte;5 write( )系统调用格式 read(fd,buf,nbyte)功能:把nbyte 个字节的数据,从buf所指向的缓冲区写到由fd所指向的文件中。如文件加锁,暂停写入,直至开锁。6 msgget( )创建一个消息,获得一个消息的描述符。核心将搜索消息队列头表,确定是否有指定名字的消息队列。若无,核心将分配一新的消息队列头,并对它进行初始化,然后给用户返回一个消息队列描述符,否则它只是检查消息队列的许可权便返回。系统调用格式:msgqid=msgget(key,flag)该函数使用头文件如下:#include#include#include参数定义int msgget(key,flag)key_t key;int flag;其中:key是用户指定的消息队列的名字;flag是用户设置的标志和访问方式。如IPC_CREAT |0400 是否该队列已被创建。无则创建,是则打开;IPC_EXCL |0400 是否该队列的创建应是互斥的。msgqid 是该系统调用返回的描述符,失败则返回-1。7 msgsnd()发送一消息。向指定的消息队列发送一个消息,并将该消息链接到该消息队列的尾部。系统调用格式: msgsnd(msgqid,msgp,size,flag)参数定义:int msgsnd(msgqid,msgp,size,flag) int msgqid,size,flag;struct msgbuf * msgp;其中msgqid是返回消息队列的描述符;msgp是指向用户消息缓冲区的一个结构体指针。缓冲区中包括消息类型和消息正文,即 long mtype; /*消息类型*/ char mtext ; /*消息的文本*/ size指示由msgp指向的数据结构中字符数组的长度;即消息的长度。这个数组的最大值由MSG-MAX( )系统可调用参数来确定。flag规定当核心用尽内部缓冲空间时应执行的动作:进程是等待,还是立即返回。若在标志flag中未设置IPC_NOWAIT位,则当该消息队列中的字节数超过最大值时,或系统范围的消息数超过某一最大值时,调用msgsnd进程睡眠。若是设置IPC_NOWAIT,则在此情况下,msgsnd立即返回。8 msgrcv( )接受一消息。从指定的消息队列中接收指定类型的消息。系统调用格式: msgrcv(msgqid,msgp,size,type,flag)参数定义: int msgrcv(msgqid,msgp,size,type,flag) int msgqid,size,flag; struct msgbuf *msgp; long type;其中,msgqid,msgp,size,flag与msgsnd中的对应参数相似,type是规定要读的消息类型,flag规定倘若该队列无消息,核心应做的操作。如此时设置了IPC_NOWAIT标志,则立即返回,若在flag中设置了MS_NOERROR,且所接收的消息大于size,则核心截断所接收的消息。9 msgctl( )消息队列的操纵。读取消息队列的状态信息并进行修改,如查询消息队列描述符、修改它的许可权及删除该队列等。系统调用格式: msgctl(msgqid,cmd,buf);参数定义: int msgctl(msgqid,cmd,buf); int msgqid,cmd; struct msgqid_ds *buf;其中,函数调用成功时返回0,不成功则返回-1。buf是用户缓冲区地址,供用户存放控制参数和查询结果;cmd是规定的命令【参考程序】任务一:29# include# include# includeint wait_mark;/阻塞状态的标志(1:阻塞;0:唤醒)void waiting(),stop();main() int p1;while(p1=fork()=-1);/进程创建失败if(p10) /在父进程中wait_mark=1;signal(SIGINT,stop);waiting(); kill(p1,16);printf(“parent process is killed!n”);else /在子进程中wait_mark=1;signal(16,stop);waiting();printf(“child process is killed!n”);void waiting() /检查进程状态 while(wait_mark!=0);void stop() / 将阻塞状态进程唤醒 wait_mark=0;任务二:#include #include #include main( ) int pid1,pid2; int fd2;char outpipe100,inpipe100;pipe(fd);while (pid1=fork( )= =-1);if(pid1= =0)sprintf(outpipe,child 1 process is sending message!); /把串放入数组outpipe中write(fd1,outpipe,50); /向管道写长为50字节的串*/ elsewhile(pid2=fork( )= =-1);if(pid2= =0) sprintf(outpipe,child 2 process is sending message!); write(fd1,outpipe,50); else read(fd0,inpipe,50); /从管道中读长为50字节的串*/printf(%sn,inpipe);read(fd0,inpipe,50);printf(%sn,inpipe);任务三:1client.c#include #include #include #define MSGKEY 75struct msgform long mtype;char mtext1000;msg;int msgqid;void client() int i;msgqid=msgget(MSGKEY,0777); /*打开75#消息队列*/for(i=10;i=1;i-) msg.mtype=i;printf(“(client)sentn”);msgsnd(msgqid,&msg,1024,0); /*发送消息*/exit(0);main( ) client( );2server.c#include #include #include #define MSGKEY 75struct msgform long mtype; char mtext1000;msg;int msgqid;void server( ) msgqid=msgget(MSGKEY,0777|IPC_CREAT); /*创建75#消息队列*/do msgrcv(msgqid,&msg,1030,0,0); /*接收消息*/ printf(“(server)receivedn”);while(msg.mtype!=1);msgctl(msgqid,IPC_RMID,0); /*删除消息队列,归还资源*/exit(0);main( ) server( );实验四 页面置换算法模拟【实验目的】 1)进一步掌握虚拟存储器的工作原理。2)通过实验理解和掌握FIFO,LRU,OPT三种页面置换算法。3)比较各种页面置换算法的优缺点。【实验要求】1)认真阅读和掌握预备知识。2)上机操作。【实验内容】1)编译opt.c,实现OPT置换算法。(源程序已给) 多次执行,查看OPT置换算法的详细置换过程及结果。2)编辑lru.c,实现LRU置换算法。(源程序已给) 多次执行exam16b,查看LRU置换算法的详细置换过程及结果。3)代码参照前两个算法自行编写,实现FIFO置换算法。 (自行设计,需在报告中给出)编译并多次执行“fifo.c”,查看FIFO置换算法的详细置换过程及结果。4)在一个程序中同时实现OPT,LRU和FIFO三种置换算法。(自行设计,需在报告中给出)编译并多次执行,比较三种置换算法在同一组数据下的运行结果并分析其原因。【实验指导】在采用请求分页机制的操作系统中,当运行一个进程的时侯,若所要访问的页面不在内存中而需要把它们调入内存,但此时内存已无空闲空间,为了保证该进程能正常运行,需选择内存中暂时不用的一个页面调出到磁盘交换区。选择调出哪个页面,由页面置换算法决定。页面置换算法的好坏,直接影响着系统的性能。一个好的页面置换算法,应尽可能选择调出较长时间内不会再访问的页面,以保证较低的缺页率。常见的页面置换算法有OPT(最佳置换算法),FIFO(先进先出算法)及LRU(最近最久未使用算法)。 一、算法描述1OPT算法假设某个进程在交换区被分为5个页面(P=5),分别以1,2,3,4,5表示。在该进程运行过程中,处理机调用它们的顺序即页地址流为:2,3,2,1,5,2,4,5,3,2,5,2而系统分配给该进程的内存空间只有3(B3)个页面,那么在使用OPT算法时,这3个页面的内存使用情况应该是:引用串23215245325222222244422233333333333155555555缺页标记( f)(f)( )(f)(f)( )(f)( )( )(f)( )( )本例共缺页6次,缺页率为6/12。2FIFO算法为了便于比较学习,例子和前面的一样。在使用FIFO算法时,这3个页面的内存使用情况应该是:引用串23215245325222225555333333332222255111444442缺页标记(f)(f)( )(f)(f)(f)(f)( )(f)( )(f)( f)本例共缺页9次,缺页率为9/12。3LRU算法为了便于比较学习,例子和前面的一样。在使用LRU算法时,这3个页面的内存使用情况应该是:引用串23215245325222222222333333355555555111444222缺页标记( f)(f)( )(f)(f)( )(f)( )(f)(f)( )( )本例共缺页7次,缺页率为7/12。二、 所涉及到的系统调用1srand函数是随机数发生器的初始化函数。 格式:void srand(unsigned seed); 使用的头文件:#include 用法:它需要提供一个种子,参数seed是rand()的种子,用来初始化rand()的起始值。有以下几种常用的方法:l srand(unsigned) time(NULL); 直接传入一个空指针l srand(int)getpid(); 使用进程的ID(getpid()来作为初始化种子,在同一个程序中这个种子是固定的。2rand()函数是产生随机数的一个随机函数。格式:int rand();l 从srand (seed)中指定的seed开始,返回一个seed, RAND_MAX(0x7fff))间的随机整数l 在标准的C库中函数rand()可以生成0RAND_MAX之间的一个随机数,其中RAND_MAX 是stdlib.h 中定义的一个整数,它与系统有关。l 如果希望rand()在每次程序运行时产生的值都不一样,必须给srand(seed)中的seed一个变值,这个变值必须在每次程序运行时都不一样(比如到目前为止流逝的时间)。l 否则,如果给seed指定的是一个定值,那么每次程序运行时rand()产生的值都会一样,虽然这个值会是seed, RAND_MAX(0x7fff))之间的一个随机取得的值。l 如果在调用rand()之前没有调用过srand(seed),效果将和调用了srand(1)再调用rand()一样(1也是一个定值)。l 一个通用的公式是:要取得a,b)之间的随机整数,使用(rand() % (b-a))+ a (结果值将含a不含b)。在a为0的情况下,简写为rand() % b。【参考程序】OPT置换算法#include #include #include #define N 12 /随机生成的页地址流的长度 #define B 3 /分配给当前进程的内存块数 #define P 5 /进程的页面数int isInBuf(int buf, int x, int *p) /返回某个数x有没有在缓冲Buf中,若在,返回其位置,否则返回1,*p为缺页次数 int i, j = -1; for (i = 0; i B; i+) if(bufi = x) j = i; break; else if (bufi = -1) /有空闲内存块(在装入最初的几个页面时) (*p)+; bufi = x; j = i; break; if(j=-1) (*p)+; return j; int oldopt(int i, int buf , int list , int f )/功能:返回下次使用距离现在最久的页面位置 int k, h, j=0, max=-1; for (k = 0; k B; k+) for (h = i; h N; h+) if (bufk = listh) / 判断物理块中的页面是否与未来页面相等 fk = h; break; if(h=N) fk = N; /寻找下次使用距离现在最久的页面 for (k = 0; k B; k+) if (max fk) max = fk; j = k; return j;int main() int listN; /程序的访页地址流 int changeN; /记录每次被替换出去的页 int bufB,fB,i,j,k; /buf是分配给进程的内存块,f记录内存中页面下次使用的时间 int resultBN; /置换的详细过程 int old; /指向将要换出去的页 int absent; /缺页次数 srand(int)time(NULL); /初始化随机数种子 printf(n The Random List:n); for (i = 0; i N; i+) /产生随机页面访

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论