操作系统原理实验报告

实 验 报 告

课程名称

实验项目

专 业 班 级 姓 名 学 号 指导教师 实验成绩

20xx年3月29日

实验1 操作系统功能认识

一、进程管理

1.背景知识

本实验要求学生掌握常用的系统操作,例如运行程序、关闭程序、查看任务管理器等。

2.实验目的

本实验帮助学生理解程序与进程的区别,了解系统进程与用户进程,了解主要操作系

统进程。

3.工具/准备工作

需要准备一台安装Windows XP操作系统的计算机。

4.实验内容与步骤

1) 开机后,不要主动运行任何应用程序,按Ctrl+Alt+Del进入任务管理器,查看“进程”标签,记录任意四个已经处于运行状态的进程。

2)请通过网络或辅助工具,了解下面系统进程的主要职责:

a) system Idle Process:监控cpu的使用,当cpu空闲的时候,则自动发送一个idle

指令,让cpu暂时停止工作(称之为挂起)。它其实反应的是cpu的空闲状态。

b) explorer:____。__________________________________

c) services服务。

d) spoolsv: 管理所有本地和网络打印队列及控制所有打印工作。 e) winlogon:Windows NT 用户登陆程序,管理用户登录和退出 。

f) system:_ ________________

3) 执行“记事本”程序,观察任务管理器,记载其对应进程名称?

a) 执行“Office Word”程序,观察任务管理器,记载其对应的进程名称?

b) ___

执行“任务管理器|查看|选择列”操作,从中选择以下列,通过观察以上两个程序的各

分量情况,分析这些列的含义:

PID

CPU:自上次以来,进程使用中央处理器的时间百分比。

线程数: 进程中运行的线程数。_____________________________________

句柄数:_标识项目。________________________________________________

二、存储管理

1.背景知识

了解计算机存储程序工作原理,了解虚拟内存概念。

2.实验目的

1) 了解内存的分配回收,虚拟内存工作过程;

3.工具/准备工作

需要准备一台运行Windows XP操作系统的计算机。

4.实验内容与步骤

1)右击“我的电脑|属性”功能,在系统属性对话框的“常规”标签中查看你所做实验

的计算机的内存大小:3.023GB

2)在系统属性对话框的“高级”标签中,进入“性能”的“设置”界面,在其中查看目

前虚拟内存设置的驱动器和大小:存于硬盘,1800M

3)进入“任务管理器”的“性能”标签,查看系统目前内存使用的情况:

a) 内存总量: b) 已用数: c) 系统缓存: d) 可用数: 4)执行“任务管理器”的“查看”下的“选择列”,将以下列显示出来,通过分析说明

各参数的含义:

内存使用:当前程序占用的内存量 内存增量:该程序占用内存增加的量,瞬时值,加到内存使用上后就清0 页面错误:由于未能从内存中找到数据而必须从磁盘检索进程数据的次数。页面错误值从进程启动时开始累计。

虚拟内存大小:匀一部分硬盘空间充当内存。

5)查看系统中耗资源最多的4个进程:

c) d) 6)查看所有“SYSTEM”进程占用的系统的内存量:_1.78GB_______________

三、文件系统

1.背景知识

本实验要求学生掌握Windows操作系统的各种文件操作方法,包括创建文件夹、复制文件、删除文件、移动文件等。

2.实验目的

本实验帮助学生理解操作系统中文件系统是如何组织文件和为用户提供各种文件操作的。

3.工具/准备工作

需要准备一台安装Windows XP操作系统的计算机。

4.实验内容与步骤

1)磁盘是存放文件的主体,右击“我的电脑”执行“管理”命令,在管理窗口中选择“磁盘管理”项目,查看系统磁盘分区情况,记录各个磁盘分区的大小、文件系统等内容:

a)

c) __________________________ d) ___________________________________

2)在C盘下创建文件夹test,在其中创建一个空的文本文件,查看test文件夹的属性,记录其大小和占用的系统空间:0字节 ,0字节。

在该文本文件中输入“北京邮电大学”六个字符,保存文件后关闭,再次查看test文件夹属性,记录其大小和占用系统的空间:14字节,4.00KB(4096字节)。

通过对以上现象的分析,解释下面一些名次含义:

硬盘分区:从实质上说就是对硬盘的一种格式化。 扇区:磁盘上的每个磁道被等分为若干个弧段,这些弧段便是磁盘的扇区 。 簇:由属性特征比较相近的互相连接成组的网格或像元。 文件系统:操作系统用于明确磁盘或分区上的文件的方法和数据结构;即在磁盘上组织文件的方法。

3)在test文件夹下创建一个word文档,在其中插入图片、文本等对象,保存文档,使其大小超过100KB。查看该文件占用磁盘空间的情况,试分析文件系统为该文档分配磁盘空间的过程:

__用于在分布式文件系统中提供基于集中策略的预分配的方法、设备和程序存储装置。使用策略规则来提供计算机系统中的文件的预分配以及扩展大小的规定_________

四、设备管理

1.背景知识

学生了解计算机的各种外部设备的使用方式,了解驱动程序的安装和卸载方法。

2.实验目的

通过实验,让学生了解各种设备与计算机进行数据交互的前提。

3.工具/准备工作

需要准备一台安装Windows XP操作系统的计算机。

4.实验内容与步骤

1) 打开“系统属性|硬件|设备管理器”窗口,记录系统中主要设备的信息:

CPU: 硬盘驱动器:_ST3500413AS________________________________________________ 声卡:Conexant HD Audio output 显卡:AMD Radeon HD 6450 鼠标:HID-compliant mouse_________________________________________________ 键盘:HID Keyboard Device_________________________________________________

2)在USB接口上插入U盘,观察屏幕右下角的任务托盘提示,记录设备安装的过程:

a) _____发现新硬件___________ b) ______安装新硬件___________________

c) _____新硬件安装完毕_______

观察“设备管理器”窗口,发生了什么变化:

_____多了一个存储卷_____________________________________________________

3)删除U盘,拔下U盘后,再次插入USB口,观察此次系统安装提示与第一次插入时有什么不同?_____没有再次安装U盘驱动_____________________________________________

在设备管理器中找到U盘设备,执行“卸载”操作,之后再次重新插入U盘,观察此次安装提示内容:___与第一次插入U盘时候一样_____________________________________

分析删除硬件与卸载硬件的区别?

__删除:就是把安装过的文件直接在硬盘清理,而不清除注册表内的键值。______ 卸载:就是通过工具或自带反安装程序把安装的文件在硬盘清楚,同时清除注册表

内的键值。

五、用户接口

1.背景知识

了解操作系统与用户进行交互的两种方式:命令界面和系统调用;

要求学生了解常用的MS DOS命令。

2.实验目的

通过命令行与操作系统进行交互,体会操作系统作为用户接口的作用。

3.工具/准备工作

需要准备一台安装Windows XP操作系统的计算机。

4.实验内容与步骤

1)执行“开始|运行”命令,输入cmd,进入命令提示符界面;

2)练习在命令行方式下,进入不同分区,不同文件目录的方法;

3)练习查看目录内容、创建文件夹、复制文件、删除文件等方法;

4)查看本机IP地址的方法,与邻近计算机进行网络连通性测试;

5)使用help命令查看更多DOS命令,并尽可能多的尝试多种DOS命令的用法;

6)在“运行”中输入以下命令,说明其功能:

Regedit:____________________________________

Perfmon:_Winmsd: __系统信息____________________________________

Mstsc: ____________________________________

Compmgmt: Logoff: __注销命令_____________________________________

7)完成教材P31页批处理文件的实验,并在系统中运行,观察运行结果。

六、实验总结

通过这次实验我对操作系统功能有了更深的认识,通过查阅书籍,翻阅课本以及老师的帮助进行了复习,并进不了许多。

这次实验使我对Window XP有了更深一步的了解,而且通过对书籍的查阅,使我知道了许多在生活中能用到的电脑技能。并且还可以解决课内的许多习题,受益匪浅。

指导教师签字: 年 月

 

第二篇:操作系统原理实验报告(最终版)

XX学校

实验报告

   

2011 年 3 月


目录

实验1  进程管理. 3

一、实验目的. 3

二、实验内容. 3

三、实验要求. 3

四、程序说明和程序流程图. 4

五、程序代码. 5

六、程序运行结果及分析. 7

七.指导教师评议. 8

实验2  进程通信. 9

一、实验目的. 9

二、实验内容. 9

三、实验要求. 9

四、程序说明和程序流程图. 9

五、程序代码. 11

七.指导教师评议. 14

实验3  存储管理. 15

一、实验目的. 15

二、实验内容. 15

三、实验要求. 15

四、程序说明和程序流程图. 16

六、程序运行结果及分析. 23

七.指导教师评议. 23

实验4  文件系统. 24

一、实验目的. 24

二、实验内容. 24

三、实验要求. 24

四、程序说明和程序流程图. 24

五、程序代码. 26

六、程序运行结果及分析. 26

七.指导教师评议. 27


实验1  进程管理

一、实验目的

1. 弄清进程和程序的区别,加深对进程概念的理解。

2. 了解并发进程的执行过程,进一步认识并发执行的实质。

3. 掌握解决进程互斥使用资源的方法。

二、实验内容

1. 管道通信

使用系统调用pipe( )建立一个管道,然后使用系统调用fork( )创建2个子进程p1和p2。这2个子进程分别向管道中写入字符串:“Child process p1 is sending message!”和“Child process p2 is sending message!”,而父进程则从管道中读出来自两个子进程的信息,并显示在屏幕上。

2. 软中断通信

使用系统调用fork( )创建2个子进程p1和p2,在父进程中使用系统调用signal( )捕捉来自键盘上的软中断信号SIGINT(即按Ctrl-C),当捕捉到软中断信号SIGINT后,父进程使用系统调用kill( )分别向2个子进程发出软中断信号SIGUSR1和SIGUSR2,子进程捕捉到信号后分别输出信息“Child process p1 is killed by parent!”和“Child process p2 is killed by parent!”后终止。而父进程等待2个子进程终止后,输出信息“Parent process is killed!”后终止。

三、实验要求

1. 根据实验内容编写C程序。

2. 上机调试程序。

3. 记录并分析程序运行结果。


四、程序说明和程序流程图

实验1管道通信——所涉及的流程图:

实验2软中断信号——所涉及的流程图:

五、程序代码

/*expe1_1.c*/

#include <stdio.h>

void main( )

{

int i, r, p1, p2, fd[2];

  char buf[50], s[50];

  pipe(fd);  /* 父进程建立管道 */

  while ((p1=fork())==-1);  /* 创建子进程P1,失败时循环 */

  if (p1==0)  /* 由子进程P1返回,执行子进程P1 */

  {

lockf(fd[1], 1, 0);  /* 加锁锁定写入端 */

    sprintf(buf, "Child process P1 is sending messages! \n");

    printf("Child process P1! \n");

    write(fd[1], buf, 50);  /* 把buf中的50个字符写入管道 */

    sleep(5);  /* 睡眠5秒,让父进程读 */

    lockf(fd[1], 0, 0);  /* 释放管道写入端 */

    exit(0);  /* 关闭P1*/

  }

  else  /* 从父进程返回,执行父进程 */

  {

while ((p2=fork())==-1);  /* 创建子进程P2,失败时循环 */

    if (p2==0)  /* 从子进程P2返回,执行子进程P2 */

{

lockf(fd[1], 1, 0);  /* 锁定写入端 */

      sprintf(buf, "Child process P2 is sending messages! \n");

      printf("Child process P2! \n");

      write(fd[1], buf, 50);  /* 把buf中的字符写入管道 */

      sleep(5);  /* 睡眠5秒,让父进程读 */

      lockf(fd[1], 0, 0);  /* 释放管道写入端 */

      exit(0);  /* 关闭P2*/

    }

    wait(0);

if ((r=read(fd[0], s, 50))== -1)

printf("cannot read pipe! \n");

    else printf("%s", s);

    wait(0);

if ((r=read(fd[0], s, 50))== -1)

printf("cannot read pipe! \n");

    else printf("%s", s);

    exit(0);

  }

}

/*exp1-2.c*/

#include<stdio.h>

#include<stdlib.h>

#include<signal.h>

int p1,p2;

void main()

{

void ppdo();

void p1do();

void p2do();

signal(SIGINT,ppdo);

p1=fork();

if(p1==0)

{

signal(SIGUSR1,p1do);

for(;;);

  }

else {

    p2=fork();

    if(p2==0) {

      signal(SIGUSR2,p2do);

      for(;;);

    }

  }

  wait(0);

  wait(0);

  printf("\nParent process is killed!\n");

  exit(0);

}

void ppdo()

{

kill(p1,SIGUSR1);

  kill(p2,SIGUSR2);

}

void p1do()

{

printf("\nChild process p1 is killed by parent!\n");

  exit(0);

}

void p2do()

{

printf("\nChild process p2 is killed by parent!\n");

  exit(0);

}

六、程序运行结果及分析

实验1管道通信运行结果截图

实验1管道通信结果分析

父进程建立后,创建了子进程P1,P2,然后P1,P2分别向管道中写入字符串“Child process p1 is sending message!”和“Child process p2 is sending message!”,父进程从管道中读取字符串。

实验2软中断通信运行结果截图

实验2软中断通信结果分析

先预设中断信号SIGINT,再先后创建子进程P1和P2,预设中断信号SIGUSR1,SIGUER2,当我们按下“Ctrl+C”时,父进程发出中断信号SIGUSR1和SIGUSR2,通知子进程P1和P2,子进程捕捉到信号后分别输出相应的信息后,终止,最后输出“Parent process is killed!”后终止。

实验后思考:

    通过这次实验,深刻地了解到了管道通信和软中断通信的详细过程,深化了老师课堂上的讲解,对整个过程的把握也更加清晰了。

    很值得的一次学习经历,做完实验,再画流程图,程序运行的细节熟悉于心,了如指掌。

七.指导教师评议

    成绩等级

实验2  进程通信

一、实验目的

1. 了解进程间通信IPC的三种方式:消息队列、共享内存和信号量。

2. 掌握使用消息队列进行进程间通信的有关系统调用和编程方法。

3. 掌握使用共享内存进行进程间通信的有关系统调用和编程方法。

二、实验内容

1. 消息队列

使用系统调用msgget( )、msgsnd( )、msgrcv( )和msgctl( ),用消息队列机制实现客户进程和服务器进程间的通信。客户进程首先建立一个描述符为msgqid的消息队列,接着向服务器进程发送一个消息正文为自己的进程标识pid且类型为1的消息,然后接收来自服务器进程的消息,并在屏幕上显示:“Client receives a message from xxxx!”,其中“xxxx”为服务器进程的进程标识。服务器进程首先捕捉软中断信号(除不能捕捉的SIGKILL),若捕捉到时则调用函数cleanup( )删除消息队列,终止服务器进程。否则重复下列操作:接收所有类型为1的消息,并在屏幕上显示:“Server receives a message from xxxx!”,其中“xxxx”为客户进程的进程标识;然后服务器进程将客户进程的进程标识作为返回消息的类型,而将自己的进程标识作为消息正文发送给客户进程。

2. 共享内存

使用系统调用shmget( )、shmat( )和shmctl( ),用共享内存机制实现进程间的通信。其中一个进程向共享内存中写入数据,另一个进程从共享内存中读出数据并显示在屏幕上。

三、实验要求

1. 根据实验内容编写C程序。

2. 上机调试程序。

3. 记录并分析程序运行结果。

四、程序说明和程序流程图

实验1消息队列流程图


五、程序代码

实验1消息队列

/* msg_client.c */

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#define MSGKEY 75

struct msgform

{

long mtype;

   char mtext[256];

}

main()

{

struct msgform msg;

  int msgqid,pid,*pint;  /* 文件主 同组用户 其他用户 rwxrwxrwx */

  msgqid=msgget(MSGKEY,0777);        /* rw-rw-rw- */

  pid=getpid();

  pint=(int*)msg.mtext;

  *pint=pid;

  msg.mtype=1;

  msgsnd(msgqid,&msg,sizeof(int),0);

  msgrcv(msgqid,&msg,256,pid,0);

  printf("client: receive from pid %d\n",*pint);

}

/* msg_server.c */

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#define MSGKEY 75

struct msgform

{ long mtype;

   char mtext[256];}msg;

int msgqid;

main()

{

int i,pid,*pint;

   extern cleanup();

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

      signal(i,cleanup);

   msgqid=msgget(MSGKEY,   0777|IPC_CREAT);

   for (;;)

     { msgrcv(msgqid,&msg,    256,1,0);

         pint=(int*)msg.mtext;

         pid=*pint;

         printf("server: receive from pid %d\n",pid);

         msg.mtype=pid;

         *pint=getpid();

          msgsnd(msgqid,&msg,

sizeof(int),0);}}

cleanup()

{

 msgctl(msgqid,IPC_RMID,0);

   exit(0);

}

实验2共享内存

#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/shm.h>

#define SHMKEY 75

#define K 1024

int shmid;

main()

{

 int i, * pint;

  char * addr;

extern char * shmat();

  shmid = shmget(SHMKEY, 8 * K, 0777);

  addr = shmat (shmid,0,0);

  pint = (int *)addr;

  while ( * pint==0 )

    for (i=0; i<256; *pint++)

      printf("%d\n", *pint++);

}

#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/shm.h>

#define SHMKEY 75

#define K 1024

int shmid;

main()

{

int i, * pint;

  char * addr;

  extern char * shmat();

  extern cleanup();

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

    sinal (i, cleanup);

  shmid = shmget (SHMKEY, 16 * K, 0777|IPC_CREAT);

  addr = shmat (shmid,0,0);

  printf("addr 0x%x \n", addr);

  pint = (int *)addr;

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

    *pint++ =i;

  pint = (int *)addr;

  *pint = 256;

  pause();

}

cleanup()

{

  shmctl (shmid, IPC_RMID, 0);

  exit(0);

}

六、程序运行结果及分析

实验1消息队列运行结果截图

客户端:

服务器端:

实验1消息队列结果分析

服务端程序监听软中断,建立消息队列,循环在队列中接收类型为1的消息,每接收一个消息向队列中增加一个类型为客户进程ID的消息。当发生软中断时,删除消息队列。

客户端进程创建和服务端相同的消息队列,并向消息队列中发送类型为1的消息,然后接收类型为客户进程ID的消息。

实验后思考:

    对消息队列的运行情况有所了解,但关于内存共享部分尚需仔细研究。

七.指导教师评议

    成绩等级

实验3  存储管理

一、实验目的

1. 了解虚拟存储管理技术的原理与特点。

2. 掌握请求页式存储管理的页面置换算法。

二、实验内容

1. 通过随机数产生一个指令序列,共320条指令。指令的地址按下述原则生成:

(1) 50%的指令是顺序执行的;

(2) 25%的指令均匀分布在前地址部分;

(3) 25%的指令均匀分布在后地址部分。

实现方法:

(1) 在[0,319]的指令地址中随机选取一起点s;

(2) 执行指令s;

(3) 顺序执行一条指令,即执行地址为s+1的指令;

(4) 在前地址[0,s]中随机选取一条地址为m的指令执行;

(5) 顺序执行一条指令,即执行地址为m+1的指令;

(6) 在后地址[m+2,319]中随机选取一条指令s;

(7) 重复(2)—(6),直到执行320次指令。

2. 将指令序列变换为页地址流,设:

(1) 页面大小为1K;

(2) 用户内存容量为4—32页面(page frame);

(3) 用户虚存容量为32K(即32页)。

若10条指令为1页,则320条指令在虚存中的存放方式为:

第0页(虚存地址[0,9])——第0条~第9条指令;

第1页(虚存地址[10,19])——第10条~第19条指令;

? ? ? ? ? ?

第31页(虚存地址[310,319])——第310条~第319条指令。

3. 计算并输出下列算法在不同内存容量下的命中率(命中率=1-缺页率)。

(1) FIFO——First In First Out Page Replacement Algorithm

(2) LRU——Least Recently Used Page Replacement Algorithm

三、实验要求

1. 根据实验内容编写C程序。

2. 上机调试程序。

3. 记录并分析程序运行结果。

四、程序说明和程序流程图

程序说明为:

1. 通过随机数产生一个指令序列,共320条指令。指令的地址按下述原则生成:

(1) 50%的指令是顺序执行的;

(2) 25%的指令均匀分布在前地址部分;

(3) 25%的指令均匀分布在后地址部分。

实现方法:

(1) 在[0,319]的指令地址中随机选取一起点s;

(2) 执行指令s;

(3) 顺序执行一条指令,即执行地址为s+1的指令;

(4) 在前地址[0,s]中随机选取一条地址为m的指令执行;

(5) 顺序执行一条指令,即执行地址为m+1的指令;

(6) 在后地址[m+2,319]中随机选取一条指令s;

(7) 重复(2)—(6),直到执行320次指令。

2. 将指令序列变换为页地址流,设:

(1) 页面大小为1K;

(2) 用户内存容量为4—32页面(page frame);

(3) 用户虚存容量为32K(即32页)。

若10条指令为1页,则320条指令在虚存中的存放方式为:

第0页(虚存地址[0,9])——第0条~第9条指令;

第1页(虚存地址[10,19])——第10条~第19条指令;

? ? ? ? ? ?

第31页(虚存地址[310,319])——第310条~第319条指令。

3. 计算并输出下列算法在不同内存容量下的命中率(命中率=1-缺页率)。

(1) FIFO——First In First Out Page Replacement Algorithm

(2) LRU——Least Recently Used Page Replacement Algorithm

流程图:

五、程序代码

#include <stdio.h>

#include <stdlib.h>

// #include <process.h>                       /* Windows环境,getpid()原型在process.h中 */

#define TRUE 1

#define FALSE 0

#define INVALID -1

#define NULL 0

#define total_instruction 320                                    /* 指令条数 */

#define total_vp 32                                           /* 虚页数 */

#define clear_period 50                                            /* NRU清0周期 */

typedef struct {                                                /* 页表结构 */

  int pn,pfn,counter,time;                                        /* counter(LFU),time(LRU) */

} pl_type;

pl_type pl[total_vp];                                                /*页表 */

struct pfc_struct {                                             /* 存储页面表 */

  int pn,pfn;

  struct pfc_struct *next;

};

typedef struct pfc_struct pfc_type;

pfc_type pfc[total_vp],*freepf_head,*busypf_head,*busypf_tail;

int diseffect,a[total_instruction];                               /* 缺页次数,指令流 */

int page[total_instruction],offset[total_instruction];

void initialize(int);

void fifo(int);

void lru(int);

void opt(int); void lfu(int); void nur(int);

void main()

{

 int s,i,j;

  srand(getpid()*10);                                              /* 进程标识作为随机数种子 */

  s=(float)319*rand()/2147483647;                                 /* 0~319 */

  // s=(float)319*rand()/32767;                                       /* 0~319 */ 

  for (i=0; i<total_instruction; i+=4)

  { a[i]=s;                                                  /* s=0~319 */

    a[i+1]=a[i]+1;                                                 /* s+1 */

    a[i+2]=(float)a[i]*rand()/2147483647;                      /*m=0~s*/

    // a[i+2]=(float)a[i]*rand()/32767;                                   /*m=0~s*/   

    a[i+3]=a[i+2]+1;                                             /* m+1*/

    s=(float)rand()*(317-a[i+2])/2147483147+a[i+2]+2;                 /* m+2~319 */

    // s=(float)rand()*(317-a[i+2])/32767+a[i+2]+2;               /* m+2~319 */   

  }

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

  {

page[i]=a[i]/10;

    offset[i]=a[i]%10;

  } 

  for (i=4;i<=32;i++)                                              /* 用户内存工作区4-32个页面 */

  {

 printf("%2d page frames",i);

    fifo(i);

    lru(i);

    opt(i); lfu(i); nur(i);

    printf("\n");

  }

}

void initialize(int total_pf)

{

 int i;

  diseffect=0;

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

  {

pl[i].pn=i;pl[i].pfn=INVALID;

     pl[i].counter=0;pl[i].time=-1;

  } 

  for (i=1;i<total_pf;i++)

  {

pfc[i-1].next=&pfc[i];pfc[i-1].pfn=i-1;

  }

  pfc[total_pf-1].next=NULL;

  pfc[total_pf-1].pfn=total_pf-1;

  freepf_head=&pfc[0];

}

void fifo(int total_pf)

{

 int i,j;

  pfc_type *p;

  initialize(total_pf);

  busypf_head=busypf_tail=NULL;                                        /* 置忙页面队列为空 */

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

    if (pl[page[i]].pfn==INVALID)                                /* 页失效 */

    { diseffect++;                                                                /* 失效次数加1 */

      if (freepf_head==NULL)                                     /* 无空闲页面 */

      { p=busypf_head->next;

        pl[busypf_head->pn].pfn=INVALID;

        freepf_head=busypf_head;

        /* 释放忙队列中的第1个页面(淘汰1页),即出队 */

        freepf_head->next=NULL;

        busypf_head=p;                                                /* 插入到空闲页面链表 */

      }

       p=freepf_head->next;

      freepf_head->next=NULL;

      freepf_head->pn=page[i];

      pl[page[i]].pfn=freepf_head->pfn;

      if (busypf_tail==NULL)                                       /* 忙队列为空时,入队 */

         busypf_head=busypf_tail=freepf_head;

      else                                                                           /* 忙队列为非空时,入队 */

      { busypf_tail->next=freepf_head;

         busypf_tail=freepf_head;}

      freepf_head=p;

    }  printf(" FIFO: %6.4f",1-(float)diseffect/320);

}

void lru(int total_pf)

{

int min,minj,i,j,present_time;

  initialize(total_pf);present_time=0;

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

  {

if (pl[page[i]].pfn==INVALID)

{

diseffect++;

      if (freepf_head==NULL)

      {

min=32767;

        for (j=0;j<total_vp;j++)                             /* 查找内存中time最小的页面 */

          if (min>pl[j].time&&pl[j].pfn!=INVALID)

          { min=pl[j].time;minj=j;}

        freepf_head=&pfc[pl[minj].pfn];                              /* 插入空闲链表 */

        pl[minj].pfn=INVALID;

        pl[minj].time=-1;

        freepf_head->next=NULL;

      }

      pl[page[i]].pfn=freepf_head->pfn;

      pl[page[i]].time=present_time;

      freepf_head=freepf_head->next;

    }

    else pl[page[i]].time=present_time;

    present_time++;

  }

  printf(" LRU: %6.4f",1-(float)diseffect/320);

}

void opt(int total_pf)

{

 int i,j,max,maxpage,d,dist[total_vp];

  initialize(total_pf);

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

  { if (pl[page[i]].pfn==INVALID)

    { diseffect++;

      if (freepf_head==NULL)

      { for (j=0;j<total_vp;j++)

            if (pl[j].pfn!=INVALID) dist[j]=32767;

            else dist[j]=0;                                     /* 页在内存中距离非0,不在内存距离为0 */

        d=1;                                                  /* 计算内存中页面与当前访问页面的距离 */

        for (j=i+1;j<total_instruction;j++)

        { if (pl[page[j]].pfn!=INVALID) dist[page[j]]=d;

           d++;

        }

        max=-1;                                                   /* 淘汰距离最远的页 */

        for (j=0;j<total_vp;j++)

           if (max<dist[j])

           { max=dist[j];maxpage=j;}

        freepf_head=&pfc[pl[maxpage].pfn];

        freepf_head->next=NULL;

        pl[maxpage].pfn=INVALID;

      }

      pl[page[i]].pfn=freepf_head->pfn;

      freepf_head=freepf_head->next;

    }

  }

  printf(" OPT: %6.4f",1-(float)diseffect/320);

}

void lfu(int total_pf)

{

 int i,j,min,minpage;

  initialize(total_pf);

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

  { if (pl[page[i]].pfn==INVALID)

    { diseffect++;

      if (freepf_head==NULL)

      { min=32767;

        for (j=0;j<total_vp;j++)

        { if (min>pl[j].counter && pl[j].pfn!=INVALID)

          { min=pl[j].counter;minpage=j;}

          pl[j].counter=0;

        }

        freepf_head=&pfc[pl[minpage].pfn];

        pl[minpage].pfn=INVALID;

        freepf_head->next=NULL;

      }

      pl[page[i]].pfn=freepf_head->pfn;

      freepf_head=freepf_head->next;

    }

    else

    pl[page[i]].counter++;

  }

  printf(" LFU: %6.4f",1-(float)diseffect/320);

}

void nur(int total_pf)

{ int i,j,dp,cont_flag,old_dp;

  initialize(total_pf);

  dp=0;

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

  { if (pl[page[i]].pfn==INVALID)

    { diseffect++;

      if (freepf_head==NULL)

      { cont_flag=TRUE;old_dp=dp;

        while (cont_flag)

        if (pl[dp].counter==0&&pl[dp].pfn!=INVALID)

          cont_flag=FALSE;      

        else

        { dp++; if (dp==total_vp) dp=0;

          if (dp==old_dp)

            for (j=0;j<total_vp;j++) pl[j].counter=0;

        }

        freepf_head=&pfc[pl[dp].pfn];

        pl[dp].pfn=INVALID;

        freepf_head->next=NULL;        

      }

      pl[page[i]].pfn=freepf_head->pfn;

      freepf_head=freepf_head->next;

    }

    else pl[page[i]].counter=1;

    if (i%clear_period==0)

      for (j=0;j<total_vp;j++) pl[j].counter=0;

  }

  printf(" NUR: %6.4f",1-(float)diseffect/320);

}


六、程序运行结果及分析

实验运行结果截图:

实验结果分析:

先随机产生320条指令,然后转化为页地址流,分别执行FIFO,LRU,OPT,LFU,NUR算法,计算出不同算法的命中率,结果显示如上图。

实验后思考:

    把单单从课堂上学到的知识,更加熟练的应用出来,体会到了计算机学科(操作系统与计算机组成)之间的互相联系。

七.指导教师评议

    成绩等级

实验4  文件系统

一、实验目的

1. 了解文件系统的功能和内部实现。

2. 熟悉有关文件系统的系统调用。

3. 掌握简单文件系统的设计方法。

二、实验内容

1. 使用有关文件系统的系统调用creat( )、open( )、close( )、read( )和write( )将文件file1.c和file2.c合并为file3.c。

2. 为Linux系统设计一个二级目录结构的文件系统,要求具有下列功能:

(1) 向用户提供以下命令:

login——用户登录

dir——列文件目录

create——创建文件

delete——删除文件

open——打开文件

close——关闭文件

read——读文件

write——写文件

(2) 文件可进行读写保护。

(3) 列文件目录时须列出文件名、文件属性(保护信息)、文件长度和物理地址。

三、实验要求

1. 根据实验内容编写C程序。

2. 上机调试程序。

3. 记录并分析程序运行结果。

四、程序说明和程序流程图

程序说明:

首先先打开文件file1.c,file2.c,再创建文件file3.c,从前面的两个文件中读出相应的内容,写如第三个文件中,之后再关闭三个文件。

流程图:


五、程序代码

#include <stdio.h>

void main(argc, argv)

int argc;

char *argv[];

{

 int fd1, fd2, fd3, n;

  char buf[512], ch='\n';

  fd1=open(argv[1], 0);  /* 打开argv[1]对应的文件,返回标识符fd1 */

  fd2=open(argv[2], 0);  /* 打开argv[2]对应的文件,返回标识符fd2 */

  fd3=creat(argv[3], 0664);  /* 创建argv[3]对应的文件,返回标识符fd3 */

  while ((n=read(fd1, buf, 512))>0) write(fd3, buf, n);

  write(fd3, &ch, 1);

  while ((n=read(fd2, buf, 512))>0) write(fd3, buf, n);

  close(fd1);

  close(fd2);

  close(fd3);

}

六、程序运行结果及分析

运行结果截图:

4-1 file1.c文件中的内容

4-2 file2.c文件中的内容

4-3 运行后file3.c文件中的内容

实验结果分析:

    首先先打开文件file1.c,file2.c,再创建文件file3.c,从前面的两个文件中读出相应的内容,写如第三个文件中,之后再关闭三个文件,最终file3.c文件中出现图4-3内容。

实验后思考:

    通过本次实验,清楚地了解了Linu文件系统的部分指令。

七.指导教师评议

    成绩等级
相关推荐