操作系统实验报告.docx
《操作系统实验报告.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告.docx(20页珍藏版)》请在冰豆网上搜索。
操作系统实验报告
实验一
题目,
熟悉Linux系统的基本操作和开发环境
目的,
熟悉和掌握Linux系统基本命令,熟悉Linux编程环境,为以后的实验打下基础。
要求
熟练掌握Linux基本文件命令;
掌握Linux编辑程序、对源代码进行编译、连接、运行及调试的过程;
认真做好预习,书写预习报告;
实验完成后要认真总结、完成实验报告。
通过实验,掌握Linux的命令及其含义;
启动、退出、ls(显示目录内容)、cp(文件或目录的复制)、mv(文件、目录更名或移动)、rm(删除文件或目录)、mkdir(创建目录)、rmdir(删除空目录)、cd(改变工作目录)…
在Linux环境下编制、调试源程序的实际过程(每一步的具体说明)。
1.编码,打开文本编辑器,编辑源代码。
2.编译,在终端用CD命令改变工作目录,使用gcc命令编译写好的C语言源代码命令如下:
gcc-otest.ctest.out
3.运行编译好的程序,在终端输入指令运行程序,指令如下:
./test.out
4.根据运行结果对程序进行调试。
实验二
题目,
模拟进程状态转换及其PCB的变化
目的,
自行编制模拟程序,通过形象化的状态显示,使学生理解进程的概念、进程之间的状态转换及其所带来的PCB内容、组织的变化,理解进程与其PCB间的一一对应关系。
要求;
设计并实现一个模拟进程状态转换及其相应PCB组织结构变化的程序;
独立设计、编写、调试程序;
程序界面应能反映出在模拟条件下,进程之间状态转换及其对应的PCB组织的变化。
进程的状态模型(三状态、五状态、七状态或其它)可自行选择
代码书写要规范,要适当地加入注释;
鼓励在实验中加入新的观点或想法,并加以实现;
认真进行预习,完成预习报告;
实验完成后,要认真总结,完成实验报告。
程序流程图;
使用的数据结构及其说明;
程序源代码、文档注释及文字说明;
//process.cpp:
定义控制台应用程序的入口点。
//
#include"stdafx.h"
intReadyQ[10];
intRstart=0;
intRend=0;
intBlockedQ[10];
intBstart=0;
intBend=0;
intRunning=0;
//入ready队列
intInRQ(intid)
{
ReadyQ[Rend]=id;
Rend=(Rend+1)%10;
return0;
}
//出ready队列
intOutRQ()
{
inti=Rstart;
Rstart=(Rstart+1)%10;
returnReadyQ[i];
}
//入block队列
intInBQ(intid)
{
BlockedQ[Bend]=id;
Bend=(Bend+1)%10;
return0;
}
//出block队列
intOutBQ()
{
inti=Bstart;
Bstart=(Bstart+1)%10;
returnBlockedQ[i];
}
//调度发生
intDispatch()
{
InRQ(Running);
Running=OutRQ();
return0;
}
//超时发生
intTimeOut()
{
InRQ(Running);
Running=OutRQ();
return0;
}
//等待事件
intEventWait()
{
InBQ(Running);
Running=OutRQ();
return0;
}
//发生事件
intEventOccurs()
{
InRQ(OutBQ());
return0;
}
//输出
intOutPut()
{
inti=0;
printf("Running:
%d\n",Running);
printf("ReadyQueue:
");
for(i=Rstart;i!
=Rend;i=(i+1)%10)
{
printf("%d,",ReadyQ[i]);
}
printf("\nBlockedQueue:
");
for(i=Bstart;i!
=Bend;i=(i+1)%10)
{
printf("%d,",BlockedQ[i]);
}
printf("\n");
return0;
}
int_tmain(intargc,_TCHAR*argv[])
{
InRQ
(1);
InRQ
(2);
InRQ(3);
InRQ(4);
while
(1)
{
switch(getchar())
{
case'd':
Dispatch();break;
case't':
TimeOut();break;
case'w':
EventWait();break;
case'o':
EventOccurs();break;
default:
break;
}
OutPut();
}
return0;
}
运行结果及其说明;
程序使用说明。
输入d:
调度
输入t:
超时
输入w:
等待
输入o:
发生
实验四
题目
进程的管道通信
目的
加深对进程概念的理解,明确进程和程序的区别;
学习进程创建的过程,进一步认识并发执行的实质;
分析进程争用资源的现象,学习解决进程互斥的方法;
学习解决进程同步的方法;
掌握Linux系统进程间通过管道通信的具体实现方法。
要求
这是一个设计型实验,要求自行、独立编制程序;
两个子进程要并发执行;
实现管道的互斥使用。
当一个子进程正在对管道进行写操作时,另一个欲写入管道的子进程必须等待。
使用系统调用lockf(fd[1],1,0)实现对管道的加锁操作,用lockf(fd[1],0,0)解除对管道的锁定;
实现父子进程的同步,当父进程试图从一空管道中读取数据时,便进入等待状态,直到子进程将数据写入管道返回后,才将其唤醒。
修改后的程序流程图
调试正确的源程序
#include
#include
#include
#include
#include
#include
#include
#include
intmain()
{
intfd[2];
intp1,p2;
pipe(fd);
while((p1=fork())==-1)
{
printf("p1forkerror");
}
while((p2=fork())==-1)
{
printf("p2forkerror");
}
printf("helloworld:
%d,%d\n",p1,p2);
if(p1==0&&p2!
=0)
{
chars1[]="s111";
lockf(fd[1],1,0);
write(fd[1],s1,10);
sleep(3);
printf("p1write:
%d,%d\n",p1,p2);
lockf(fd[1],0,0);
exit(0);
}
if(p2==0&&p1!
=0)
{
chars1[]="s222";
lockf(fd[1],1,0);
write(fd[1],s1,10);
sleep(3);
printf("p2write:
%d,%d\n",p1,p2);
lockf(fd[1],0,0);
exit(0);
}
wait(0);
if(p1!
=0&&p2!
=0)
{
chars2[10]="";
chars3[10]="";
lockf(fd[0],1,0);
if(read(fd[0],s2,10)==-1)
{
printf("readerror");
}
if(read(fd[0],s3,10)==-1)
{
printf("readerror");
}
sleep(3);
lockf(fd[0],0,0);
printf("%s\n%s\n",s2,s3);
printf("pppread:
%d,%d\n",p1,p2);
}
return0;
}
运行结果及说明
回答问题:
进程间的互斥表现在哪里?
进程占用公用资源时会产生互斥。
进程间的同步表现在哪里?
一个进程要等待另一个进程操作结束。
你的程序采用什么方法实现上述关系?
加锁机制。
实验五
题目,
页面置换算法
目的,
进一步理解父子进程之间的关系
理解内存页面调度的机理
掌握页面置换算法的实现方法
通过实验比较不同调度算法的优劣
培养综合运用所学知识的能力
页面置换算法是虚拟存储管理实现的关键,通过本次试验理解内存页面调度的机制,在模拟实现FIFO、LRU等经典页面置换算法的基础上,比较各种置换算法的效率及优缺点,从而了解虚拟存储实现的过程。
将不同的置换算法放在不同的子进程中加以模拟,培养综合运用所学知识的能力。
内容,要求
这是一个综合型实验,要求在掌握父子进程并发执行机制和内存页面置换算法的基础上,能综合运用这两方面的知识,自行编制程序
程序涉及一个父进程和两个子进程。
父进程使用rand()函数随机产生若干随机数,经过处理后,存于一数组Acess_Series[]中,作为内存页面访问的序列。
两个子进程根据这个访问序列,分别采用FIFO和LRU两种不同的页面置换算法对内存页面进行调度。
要求:
每个子进程应能反映出页面置换的过程,并统计页面置换算法的命中或缺页情况。
设缺页的次数为diseffect。
总的页面访问次数为total_instruction。
缺页率=disaffect/total_instruction
命中率=1-disaffect/total_instruction
将为进程分配的内存页面数mframe作为程序的参数,通过多次运行程序,说明FIFO算法存在的Belady现象。
程序流程图
程序源代码、文档注释及文字说明
#include
#include
#include
#include
#include
#include
#include
#include
#definetotal18
#defineframe_num3
structone_frame
{
intpage_no;
charflag;//T琛ㄧず闈炵┖锛孎琛ㄧず绌?
};
structone_frameM_Frame[frame_num];
intdiseffact=0;
intInFrame(intn)
{
inti=0;
for(i=0;i{
if(M_Frame[i].page_no==n&&M_Frame[i].flag=='T')
{
return1;
}
//printf("testinframe,n=%d,page_no=%d\n",n,M_Frame[i].page_no);
}
return0;
}
voidClearFrame()
{
inti=0;
for(i=0;i{
M_Frame[i].flag=='F';
}
}
voidPrintFrame()
{
inti=0;
printf("frame:
");
for(i=0;i{
printf("%d,",M_Frame[i].page_no);
}
putchar('\n');
}
voidFIFO(intn)
{
inti=0;
if(InFrame(n)==1)
{
return;
}
else
{
diseffact++;
for(i=0;i{
if(M_Frame[i].flag!
='T')
{
M_Frame[i].flag='T';
M_Frame[i].page_no=n;
//printf("testadd,n=%d,page_no=%d\n",n,M_Frame[i].page_no);
return;
}
}
for(i=1;i{
M_Frame[i-1].page_no=M_Frame[i].page_no;
}
M_Frame[i-1].page_no=n;
return;
}
}
voidLRU(intn)
{
inti=0;
if(InFrame(n)==1)
{
for(i=0;i{
if(M_Frame[i].page_no==n)
{
break;
//printf("testadd,n=%d,page_no=%d\n",n,M_Frame[i].page_no);
}
else
{
}
}
for(;i{
//printf("testadd,n=%d,page_no=%d\n",n,M_Frame[i].page_no);
if(M_Frame[i+1].flag=='T')
{
M_Frame[i].page_no=M_Frame[i+1].page_no;
}
else
{
break;
}
}
M_Frame[i].page_no=n;
return;
}
else
{
diseffact++;
for(i=0;i{
if(M_Frame[i].flag!
='T')
{
M_Frame[i].flag='T';
M_Frame[i].page_no=n;
//printf("testadd,n=%d,page_no=%d\n",n,M_Frame[i].page_no);
return;
}
}
for(i=1;i{
M_Frame[i-1].page_no=M_Frame[i].page_no;
}
M_Frame[i-1].page_no=n;
return;
}
}
intmain()
{
//鍒濆鍖栧唴瀛?
inti=0;
intAccess_Series[total];
srand((unsigned)time(NULL));
for(i=0;i{
Access_Series[i]=rand()%6+1;
}
intp1=0;
while((p1=fork())==-1)
{
printf("p1forkerror");
}
if(p1==0)
{
printf("P1run\n");
//娓呯┖缂撳瓨
ClearFrame();
inti=0;
for(i=0;i{
intn=Access_Series[i];
//printf("P1:
n%d=%d,dis=%d\n",i,n,diseffact);
FIFO(n);
PrintFrame();
}
//printf("P1overdiseffect=%d\n",diseffact);
}
else
{
intp2=0;
while((p2=fork())==-1)
{
printf("p2forkerror");
}
if(p2==0)
{
printf("P2run\n");
//娓呯┖缂撳瓨
ClearFrame();
inti=0;
for(i=0;i{
intn=Access_Series[i];
printf("P2:
n%d=%d,dis=%d\n",i,n,diseffact);
LRU(n);
PrintFrame();
}
printf("P2overdiseffect=%d\n",diseffact);
}
else
{
wait(0);
printf("mainover\n");
}
}
}
运行结果及其说明
回答以下问题:
父进程空间与子进程间的关系。
父进程创建子进程1,子进程1执行,子进程1执行同时父进程执行并创建子进程2,子进程2执行,、父进程等待子进程,程序结束。
通过完成实验,根据你的体会,阐述虚拟存储器的原理。
虚拟存储器可以分为三类:
页式、段式和段页式。
本实验我们主要学习页式虚拟存储器。
在页式虚拟存储器中通过把主存空间和程序空间都机械等分成固定大小的页(页面大小随机器而定,一般为4kB到4MB),按页顺序编号,用相应的映像表机构来指明该程序的某页是否已经装入主存。
若已经装入主存,则应同时指明其在主存中所处的位置;如果未装入主存,则去辅存中调页,并建立起程序空间和实存空间的地址映像关系。
这样,程序执行时通过查映像表将程序地址(虚拟地址)变换成实际主存地址(物理地址)再访问主存。
写出FIFO算法中出现Belady现象的内存页面访问序列
假如一个作业的页面走向为4、3、2、1、4、3、5、4、3、2、1、5,当分配给该作业的物理块数M分别为3和4时,试计算在访问过程中所发生的缺页次数和缺页率,并比较所得结果。
3块:
44块:
4
4|34|3
4|3|24|3|2
3|2|14|3|2|1
2|1|43|2|1|4
1|4|32|1|4|3
4|3|51|4|3|5
4|3|51|3|5|4
4|3|51|5|4|3
3|5|25|4|3|2
5|2|14|3|2|1
5|2|13|2|1|5
当M=3时,采用FIFO页面置换算法的缺页次数为9次,缺页率为75%;
当M=4时,采用FIFO页面置换算法的缺页次数为10次,缺页率为83%。
由此可见,增加分配给作业的内存块数,反而增加了缺页次数,提高了缺页率,出现了Belady现象