操作系统实践报告.docx
《操作系统实践报告.docx》由会员分享,可在线阅读,更多相关《操作系统实践报告.docx(18页珍藏版)》请在冰豆网上搜索。
操作系统实践报告
《操作系统》实践报告
准考证号:
考生姓名:
一.实验目的
操作系统是一门实践性很强的计算机专业课程,它要求我们掌握操作系统的工作原理和基本理论知识。
它注重方法、技术的实际应用。
在上机实践考核中,为培养考生良好的学习与工作作风。
要求考生按一定的规范进行上机前的考核准备。
熟悉软硬件环境。
上机调试和正确运行程序,以及提交实践考核报告。
上机实践考核在机器环境上调试、运行程序和产生正确的结果。
但准备阶段和整理实践报告也十分重要,只有做好充分的准备,熟悉机器及环境,尽可能的正确编码,才能高效率地利用机时。
在书写报告时,必须依照规定的格式整理好文档资料,为考生将来从事于软件开发和研制工作,打下一个坚实的基础。
二.实验环境
1.硬件环境:
CPU:
P42.4GHz
内存:
256M
硬盘:
40G(局域网)
2.软件环境:
操作系统:
WindowsXP
开发工具:
MicrosoftVisualC++6.0
三.实验内容
3.1实验六
1.内容描述
在Windows环境下创建子进程,在父子进程之间实验进程通信。
2.实验过程
2.1实验原理:
系统内部进程间通讯和数据交换有多种方式:
消息、共享内存、匿名(命名)管道、邮槽、Windows套接字等多种技术。
其中利用消息机制实现IPC虽然同其他方法相比有交换的数据量小、携带的信息少等缺点,但由于其实现方便、应用灵活而广泛应用于无须大量、频繁数据交换的内部进程通讯系统之中。
Windows是一种面向对象的体系结构,Windows环境和应用程序都是通过消息来交互的。
Windows应用程序开始执行后,Windows为该程序创建一个"消息队列(messagequeue)",用以存放邮寄给该程序可能创建的各种不同窗口的消息。
消息队列中消息的结构(MSG)为
typedefstructtagMSG{
HWNDhwnd;
UINTmessage;
WPARAMwParam;
LPARAMlParam;
DWORDtime;
POINTpt;
}MSG;
其中第一个成员变量是用以标识接收消息的窗口的窗口句柄;第二个参数便是消息标识号,如WM_PAINT;第三个和第四个参数的具体意义同message值有关,均为消息参数。
前四个参数是非常重要和经常用到的,至于后两个参数则分别表示邮寄消息的时间和光标位置(屏幕坐标)。
把消息传送到应用程序有两种方法:
一种是由系统将消息"邮寄(post)"到应用程序的"消息队列"这是"进队消息"Win32API有对应的函数PostMessage(),此函数不等待该消息处理完就返回;而另一种则是由系统在直接调用窗口函数时将消息"发送(send)"给应用程序的窗口函数,属于"不进队消息"对应的函数是SendMessage()其必须等待该消息处理完后方可返回。
2.2父进程的实现
1)新建一工程文件:
FatherProcess,选取MFCAppWizard(exe)。
2)第二步选取Singledocument(单文档)。
3)其余几步均为确省值。
4)添加三个菜单“进程通信”,子菜单“向“子进程”发送命令“和与其对应的函数:
//FatherProcessView.cpp文件中,向子进程发送命令
voidCFatherProcessView:
:
OnMenuCommand1()
{
//TODO:
Addyourcommandhandlercodehere
CStringstr="Son(子进程)";
CWnd*pWnd=CWnd:
:
FindWindow(NULL,str);
if(pWnd)
pWnd->SendMessage(WM_COMM,0,0);
}
在FatherProcessView.h中
添加自定义消息:
#defineWM_COMMWM_USER+100。
5)在MainFrame.cpp文件中,添加收到子进程命令的消息函数:
BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)
……
ON_MESSAGE(WM_MSG_TOFATHER,OnToFatherMsg)
END_MESSAGE_MAP()
voidCMainFrame:
:
OnToFatherMsg(WPARAMwParam,LPARAMlParam)
{
if(wParam==0&&lParam==0)
{
AfxMessageBox("收到,Son,“命令”");
}
}
在MainFrame.h文件中修改如下:
a)添加自定义消息:
#defineWM_MSG_TOFATHERWM_USER+101
b)添加头文件定义
voidOnToFatherMsg(WPARAMwParam,LPARAMlParam)
6)在BOOLCFatherProcessApp:
:
InitInstance()函数末尾添加:
m_pMainWnd->SetWindowText("Father(父进程)");//非常重要,否则消息将收不到
7)编译调试并运行程序。
2.3子进程的实现
1)新建一工程文件:
SonProcess,选取MFCAppWizard(exe)。
2)第二步选取Singledocument(单文档)。
3)其余几步均为确省值。
4)添加三个菜单“进程通信”,子菜单“向“父进程”发送命令“和与其对应的函数:
//SonProcessView.cpp文件中,//向父进程发送命令
voidCSonProcessView:
:
OnMenuitemCommand1()
{
CStringstr="Father(父进程)";
CWnd*pWnd=CWnd:
:
FindWindow(NULL,str);
if(pWnd)
pWnd->SendMessage(WM_MSG_TOFATHER,0,0);
}
在SonProcessView.h中
添加自定义消息:
#defineWM_MSG_TOFATHERWM_USER+101
5)在MainFrame.cpp文件中,添加收到子进程命令的消息函数:
BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)
……
ON_MESSAGE(WM_COMM,OnSendMsg)
END_MESSAGE_MAP()
voidCMainFrame:
:
OnSendMsg(WPARAMwParam,LPARAMlParam)
{
if(wParam==0&&lParam==0)
{
AfxMessageBox("收到,Father,“命令”");
}
}
在MainFrame.h文件中修改如下:
a)添加自定义消息:
#defineWM_MSG_TOFATHERWM_USER+101
b)添加头文件定义
voidOnSendMsg(WPARAMwParam,LPARAMlParam);
6)在BOOLCSonProcessApp:
:
InitInstance()函数末尾添加:
m_pMainWnd->SetWindowText("Son(子进程)");//非常重要,否则消息将收不到
7)编译调试并运行程序。
3.运行结果
父进程向子进程发送消息结果如下图:
3.2实验七
1.内容描述
编程模拟磁盘移臂调度算法。
2.实验过程
程序清单:
//*****************实验七:
模拟磁盘移臂调度程序*******************
#include"stdio.h"
#include"stdlib.h"
voidCopyL(intSour[],intDist[],intx);//数组Sour复制到数组Dist,复制到x个数
voidSetDI(intDiscL[]);//随机生成磁道数
voidPrint(intPri[],intx);//打印输出数组Pri
voidDelInq(intSour[],intx,inty);//数组Sour把x位置的数删除,并把y前面的数向前移动,y后的数保持不变(即会出现2个y)
voidFCFS(intHan,intDiscL[]);//先来先服务算法(FCFS)
voidSSTF(intHan,intDiscL[]);//最短寻道时间优先算法(SSTF)
intSCAN(intHan,intDiscL[],intx,inty);//单向扫描算法(SCAN)
voidCSCAN(intHan,intDiscL[]);//电梯调度扫描算法(CSCAN)
voidPaiXu();//寻道长度由低到高排序
intNAll=0;
intBest[5][2];//用作寻道长度由低到高排序时存放的数组
intLimit=0;//输入寻找的范围磁道数i
intJage;
floatAver=0;
intmain()
{
inti;
intDiscLine[10];//声明准备要生成的随机磁道号的数组
intHand;//磁道数
intCon=1;
intn;
while(Con==1)
{
Jage=0;
Hand=143;//初始的磁道数
Limit=300;//输入寻找的范围
if(Limit>65536)
{
printf("超出范围!
");
}
else
{
printf("*********************************************\n");
printf("****************磁盘调度算法******************\n");
printf("*********************************************\n");
printf(" *1.先来先服务算法(FCFS)*\n");
printf("*2.最短寻道时间优先算法(SSTF)*\n");
printf("*3.单向扫描算法(CSCAN)*\n");
printf("*4.电梯调度算法(SCAN)*\n");
printf("*********************************************\n");
scanf("%d",&n);
if(n==0)
exit(0);
printf("\n");
switch(n)
{
case1:
SetDI(DiscLine);
FCFS(Hand,DiscLine);//先来先服务算法(FCFS)
break;
case2:
SetDI(DiscLine);
SSTF(Hand,DiscLine);//最短寻道时间优先算法(SSTF)
break;
case3:
SetDI(DiscLine);
CSCAN(Hand,DiscLine);//单向扫描算法(CSCAN)
break;
case4:
SetDI(DiscLine);
SCAN(Hand,DiscLine,0,9);//电梯调度算法(SCAN)
break;
case5:
break;
}
printf("\n\n+是否继续(按0结束,按1继续)?
");
scanf("%5d",&Con);
}
}
}
//数组Sour复制到数组Dist,复制到x个数
voidCopyL(intSour[],intDist[],intx)
{
inti;
for(i=0;i<=x;i++)
{
Dist[i]=Sour[i];
}
}
//打印输出数组Pri
voidPrint(intPri[],intx)
{
inti;
for(i=0;i<=x;i++)
{
printf("%5d",Pri[i]);
}
}
//随机生成磁道数
voidSetDI(intDiscL[])
{
inti;
intnQueue[QUEUELEN]={143,86,145,93,179,95,150,103,176,132};
for(i=0;i{
DiscL[i]=nQueue[i];//随机生成10个磁道号
}
printf("+需要寻找的磁道号:
");
Print(DiscL,9);//输出随机生成的磁道号
printf("\n");
}
//数组Sour把x位置的数删除,并把y前面的数向前移动,y后的数保持不变(即会出现2个y)
voidDelInq(intSour[],intx,inty)
{
inti;
for(i=x;i{
Sour[i]=Sour[i+1];
x++;
}
}
//先来先服务算法(FCFS)
voidFCFS(intHan,intDiscL[])
{
intRLine[10];//将随机生成的磁道数数组Discl[]复制给数组RLine[]
inti,k,All,Temp;//Temp是计算移动的磁道距离的临时变量
All=0;//统计全部的磁道数变量
k=9;//限定10个的磁道数
CopyL(DiscL,RLine,9);//复制磁道号到临时数组RLine
printf("\n+按照FCFS算法磁道的访问顺序为:
");
All=Han-RLine[0];
for(i=0;i<=9;i++)
{
Temp=RLine[0]-RLine[1];//求出移动磁道数,前一个磁道数减去后一个磁道数得出临时的移动距离
if(Temp<0)
Temp=(-Temp);//移动磁道数为负数时,算出相反数作为移动磁道数
printf("%5d",RLine[0]);
All=Temp+All;//求全部磁道数的总和
DelInq(RLine,0,k);//每个磁道数向前移动一位
k--;
}
Best[Jage][1]=All;//Best[][1]存放移动磁道数
Best[Jage][0]=1;//Best[][0]存放算法的序号为:
1
Jage++;//排序的序号加1
Aver=((float)All)/10;//求平均寻道次数
printf("\n+臂移动总量:
<%5d>",All);
}
//最短寻道时间优先算法(SSTF)
voidSSTF(intHan,intDiscL[])
{
inti,j,k,h,All;
intTemp;//Temp是计算移动的磁道距离的临时变量
intRLine[10];//将随机生成的磁道数数组Discl[]复制给数组RLine[]
intMin;
All=0;//统计全部的磁道数变量
k=9;//限定10个的磁道数
CopyL(DiscL,RLine,9);//复制磁道号到临时数组RLine
printf("\n+按照SSTF算法磁道的访问顺序为:
");
for(i=0;i<=9;i++)
{
Min=64000;
for(j=0;j<=k;j++)//内循环寻找与当前磁道号最短寻道的时间的磁道号
{
if(RLine[j]>Han)//如果第一个随机生成的磁道号大于当前的磁道号,执行下一句
Temp=RLine[j]-Han;//求出临时的移动距离
else
Temp=Han-RLine[j];//求出临时的移动距离
if(Temp{
Min=Temp;//Temp临时值赋予Min
h=j;//把最近当前磁道号的数组下标赋予h
}
}
All=All+Min;//统计一共移动的距离
printf("%5d",RLine[h]);
Han=RLine[h];
DelInq(RLine,h,k);//每个磁道数向前移动一位
k--;
}
Best[Jage][1]=All;//Best[][1]存放移动磁道数
Best[Jage][0]=2;//Best[][0]存放算法的序号为:
2
Jage++;//排序序号加1
Aver=((float)All)/10;//求平均寻道次数
printf("\n+臂移动总量:
<%5d>",All);
}
//扫描算法(SCAN)
intSCAN(intHan,intDiscL[],intx,inty)
{
intj,n,k,h,m,All;
intt=0;
intTemp;
intMin;
intRLine[10];//将随机生成的磁道数数组Discl[]复制给数组RLine[]
intOrder;
Order=1;
k=y;
m=2;//控制while语句的执行,即是一定要使当前磁道向内向外都要扫描到
All=0;//统计全部的磁道数变量
CopyL(DiscL,RLine,9);//复制磁道号到临时数组RLine
printf("\n+按照电梯调度算法磁道的访问顺序为:
");
Min=64000;
for(j=x;j<=y;j++)//寻找与当前磁道号最短寻道的时间的磁道号
{
if(RLine[j]>Han)//如果第一个随机生成的磁道号大于当前的磁道号,执行下一句
Temp=RLine[j]-Han;//求出临时的移动距离
else
Temp=Han-RLine[j];//求出临时的移动距离
if(Temp{
Min=Temp;//Temp临时值赋予Min
h=j;//把最近当前磁道号的数组下标赋予h
}
}
All=All+Min;
printf("%5d",RLine[h]);
if(RLine[h]>=Han){//判断磁道的移动方向,即是由里向外还是由外向里
Order=0;
t=1;
}
Han=RLine[h];
DelInq(RLine,h,k);//每个磁道数向前移动一位
k--;
while(m>0)
{
if(Order==1)//order是判断磁盘扫描的方向标签,order是1的话,磁道向内移动
{
for(j=x;j<=y;j++)
{
h=-1;
Min=64000;
for(n=x;n<=k;n++)//判断离当前磁道最近的磁道号
{
if(RLine[n]<=Han)
{
Temp=Han-RLine[n];
if(Temp{
Min=Temp;//Temp临时值赋予Min
h=n;//把最近当前磁道号的数组下标赋予h
}
}
}
if(h!
=-1)
{
All=All+Min;//叠加移动距离
printf("%5d",RLine[h]);
Han=RLine[h];//最近的磁道号作为当前磁道
DelInq(RLine,h,k);
k--;
}
}
Order=0;//当完成向内的移动,order赋予0,执行else语句,使磁道向外移动
m--;//向内完成一次,m减一次,保证while循环执行两次
}
else//order是0的话,磁道向外移动
{
for(j=x;j<=y;j++)
{
h=-1;
Min=64000;
for(n=x;n<=k;n++)//判断离当前磁道最近的磁道号
{
if(RLine[n]>=Han)
{
Temp=RLine[n]-Han;
if(Temp{
Min=Temp;//Temp临时值赋予Min
h=n;//把最近当前磁道号的数组下标赋予h
}
}
}
if(h!
=-1)
{
All=All+Min;//叠加移动距离
printf("%5d",RLine[h]);
Han=RLine[h];//最近的磁道号作为当前磁道
DelInq(RLine,h,k);
k--;
}
}
Order=1;//当完成向内的移动,order赋予0,执行else语句,使磁道向外移动
m--;//向内完成一次,m减一次,保证while循环执行两次
}
}
NAll=NAll+All;
if((y-x)>5)
{
Best[Jage][1]=All;//Best[][1]存放移动磁道数
Best[Jage][0]=3;//Best[][0]存放算法的序号为:
3
Jage++;//排序序号加1
Aver=((float)All)/10;//求平均寻道次数
printf("\n+臂移动总量:
<%5d>",All);
}
return(Han);
}
//单向扫描算法(CSCAN)
voidCSCAN(intHan,intDiscL[])
{
intj,h,n,Temp,m,k,All,Last,i;
intRLine[10];//将随机生成的磁道数数组Discl[]复制给数组RLine[]
intMin;
inttmp=0;
m=2;
k=9;
All=0;//统计全部的磁道数变量
Last=Han;
CopyL(DiscL,RLine,9);//复制磁道号到临时数组RLine
printf("\n+按照单向扫描算法磁道的访问顺序为:
");
while(k>=0)
{
for(j=0;j<=9;j++)//从当前磁道号开始,由内向外搜索离当前磁道最