实验报告
实验课程: 计算机操作系统
学生姓名: XXX
学 号: XXXX
专业班级: 软件
20##年12月25日
目录
实验一 熟悉Windows XP中的进程和线程... 3
实验二 进程调度... 7
实验三 死锁避免—银行家算法的实现... 16
实验四 存储管理... 22
实验一 熟悉Windows XP中的进程和线程
一、 实验名称
熟悉Windows XP中的进程和线程
二、 实验目的
1、熟悉Windows中任务管理器的使用。
2、通过任务管理器识别操作系统中的进程和线程的相关信息。
3、掌握利用spy++.exe来察看Windows中各个任务的更详细信息。
三、 实验结果分析
1、启动操作系统自带的任务管理器:
方法:直接按组合键Ctrl+Alt+Del,或者是在点击任务条上的“开始”“运行”,并输入“taskmgr.exe”。
2、调整任务管理器的“查看”中的相关设置,显示关于进程的以下各项信息,并完成下表:
表一:统计进程的各项主要信息
3、启动办公软件“Word”,在任务管理器中找到该软件的登记,并将其结束掉。再从任务管理器中分别找到下列程序:winlogon.exe、lsass.exe、csrss.exe、smss.exe,试着结束它们,观察到的反应是 任务管理器无法结束进程 ,
原因是 该系统是系统进程 。
4、在任务管理器中找到进程“explorer.exe”,将之结束掉,并将桌面上你打开的所有窗口最小化,看看你的计算机系统起来什么样的变化 桌面上图标菜单都消失了 、得到的结论 explorer.exe是管理桌面图标的文件 (说出explorer.exe进程的作用)。
5、运行“spy++.exe”应用软件,点击按钮“”,切换到进程显示栏上,查看进程“explorer.exe”的各项信息,并填写下表:
进程:explorer.exe 中的各个线程
6、注意某些线程前有“+”,如图所示:,说明二者之间的差异前有“+”其器线程下有窗口 。
四、 心得体会
通过本次实验,我了解到了windows系统中进程的管理与操作,我了解了如何切出任务管理器,任务管理器应用与其他与进程相关的知识,明白了有些系统程序不能够关闭,系统中的进程与线程虽然很多,但是其中有许多关联,只要弄清楚其中的关联那么就能够运用好进程与线程,达到我们的目的。
每个进程下都包含着许多线程,我们控制进程来达到控制线程的目的只有我们了解好掌握还进程,我们才能更好的运用线程,更好的控制运用计算机。
实验二 进程调度
一、 实验名称
进程调度
二、 实验目的
1、使学生进一步理解进程的概念,并在此基础上掌握有关PCB、进程队列的概念。
2、掌握进程基本状态的转化;
3、 掌握进程调度的策略、具体实施方法以及系统性能的评价方法。
三、实验结果分析
简化的实验代码如下:
#include<iostream>
#include<queue>//调用STL中的优先队列
using namespace std;
//定义一个PCB进程类
class PCB
{
public:
char name[10];//进程的名字
int runtime;//该进程的运行时间
int priority;//该进程的优先级
char state;//该进程的状态
PCB* next;//指向下个进程的指针
void print()const//输出进程的信息
{
cout<<"(name="<<name<<",runtime="<<runtime<<",state="<<state
<<",priority="<<priority<<")"<<endl;
}
};
class PCBSortCriterion{//优先队列的优先准则类
public:
bool operator()(const PCB & p1,const PCB & p2)const//仿函数确定优先准则,从大到小
{
return (p1.priority < p2.priority);
}
};
PCB* pcb=new PCB[number];//一个PCB的数组用来保存就绪进程
PCB* p1=new PCB[number];//一个PCB的数组用来保存已经结束的进程
cout<<endl;
PCB p;//一个PCB型的变量,用来保存队首元素
int i;
for( i=0 ;i<=number-1;i++)//建立进程信息
cout<<"请输入pcb["<<i<<"]的信息!"<<endl;
cout<<"以(name,runtime,state(初始为R),priority)格式输入!"<<endl;
cin>>pcb[i].name;
cin>>pcb[i].runtime;
cin>>pcb[i].state;
cin>>pcb[i].priority;
cout<<endl;
}
typedef priority_queue<PCB,vector<PCB> ,PCBSortCriterion> pQueue;//以 //PCBSortCriterion为
//优先准则的优先队列
pQueue q,// 优先队列pQueue的一个对象,对这个队列进行主操作
temp;//优先队列pQueue的一个对象,是q的一个拷贝对象,作为实现打印输出//的一个中间变量
for(int j=0;j<=number-1;j++)//将进程入队建立优先队列
{
q.push(pcb[j]);
}
//输出进程控制块的初始状态信息
cout<<"进程控制块的初始状态信息为:"<<endl;
temp=q;
while(!temp.empty())
{
p=temp.top();
p.print();
temp.pop();
}
cout<<endl;
int n=0, //进程执行的次数
m=0;//完成进程的个数
while(!q.empty())//对进程进行调度
{
cout<<"第"<<++n<<"次运行";
p=q.top();
cout<<q.top().name<<"!"<<endl;
p.runtime-=1;
p.priority-=1;
q.pop();
if(p.runtime!=0)//表明该进程还未执行完 ,继续入队进行操作
{
q.push(p);
}
else {//表明该进程已经执行完,设置其状态为Z,并将其保存到p1中
p.state='Z';
p1[m++]=p;
}
cout<<"运行后的状态为:"<<endl;
//打印出运行后的进程状态
temp=q;//拷贝输出队列
while(!temp.empty())
{
p=temp.top();
p.print();
temp.pop();
}
if(m>0)//输出完成的进程的信息
for( i=0;i<=m-1;i++)
p1[i].print();
cout<<endl;
cout<<endl;
}
system("pause");
return 0;
}
int main()
{
cout<<setw(40)<<"进程模拟调度设计"<<endl<<endl;
cout<<"提示:输入1选择先来先服务算法,输入2选择优先级法,输入3选择轮转法,输入4退出程序"<<endl<<endl;
cout<<" 1、先来先服务\n 2、优先级法\n 3、时间片轮转法\n 4.多级反馈轮转法\n 5.动态优先级法\n 6.退出"<<endl<<endl;
int choice;
int go=1;
while(go)
{
cout<<"请输入你的选择:";
cin>>choice;
switch(choice)
{
//调用先来先服务算法求解
case 1: FCFS();break;
//调用优先级法求解
case 2: PRIO();break;
//调用时间片轮转法求解
case 3: LZF();break;
//调用多级反馈轮转法求解
case 4: DJFKLZ();break;
case 5: DTYXJF();break;
case 6: cout<<"退出"<<endl;go=0;break;
//返回首页
default: cout<<"选择有误,请重新输入选择!"<<endl;break;
}
}
system("pause");
return 0;
}
程序运行结果:
初始化界面:
先来先服务法:
静态优先级法:
时间片轮转法:
.
动态优先级法:
多级反馈轮转法:
四、心得体会
1、通过这次实验使得我对进程调度几种算法的思想以及实现原理有了进一步的认识和掌握。在设计多级反馈轮转法的算法以及实现代码时,遇到了代码不会写,算法理解不够透彻的问题,而导致在这个问题上纠结了很久。最后还是在查阅资料以及同组成员的讨论下解决了。
2、这次实验使用的编程语言是C。由于在以前学习C的时候掌握的不是很好和很多知识点都忘记了以至于在实验的很多地方(如实验界面和代码的精简)做得不是很好,以后得注意对C的学习和巩固。
3、也使我更能体会到集体的力量永远要大于个人。在实验中我们遇见的很多问题基本上都是一起讨论才解决的。
4. 一开始以为涉及到操作系统的模拟编程的都是高不可攀的,然而在仔细阅读课本以及实验说明后,发现只要弄清楚了优先级数调度的实现原理后其实并不难,用优先队列就可以了。通过这个实验一来加深了对优先级数调度的理解,二来也加强了自己的编程实践能力!
实验三 死锁避免—银行家算法的实现
一、实验名称
死锁避免—银行家算法的实现
二、实验目的
1、掌握死锁产生的原因和必要条件。
2、掌握银行家算法的实现
三、实验结果分析
#include <iostream>
using namespace std;
#define mp 50 //最大进程数
#define mr 100 /最大资源数
int keyong[mr]; //可用资源数组
int MAX[mp][mr]; //最大需求矩阵
int fenpei[mp][mr]; //分配矩阵
int need[mp][mr]; //剩余需求矩阵
bool FINISH[mp]; //系统是否有足够资源分配
int p[mp]; //记录序列
int Work[mr]; //工作数组
int m,n; //m个进程,n个资源
int l=0;
void Init(); //初始化
bool Safe();
void jc();
void main()
{ Init();
Safe();
if(l!=m)
jc();}
void Init() //初始化算法
{ int i,j;
cout<<"请输入进程的数目:";
cin>>m;
cout<<"请输入资源的种类:";
cin>>n;
cout<<"请输入每个进程最多所需的各资源数,按照"<<m<<"x"<<n<<"矩阵输入"<<endl;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
cin>>MAX[i][j];
cout<<"请输入每个进程已分配的各资源数,也按照"<<m<<"x"<<n<<"矩阵输入"<<endl;
for(i=0;i<m;i++)
{ for(j=0;j<n;j++)
{
cin>>fenpei[i][j];
need[i][j]=MAX[i][j]-fenpei[i][j];
if(need[i][j]<0)
{ cout<<"您输入的第"<<i+1<<"个进程所拥有的第"<<j+1<<"个资源数错误,请重新输入:"<<endl; j--;
continue; }
}
}
cout<<"请输入各个资源现有的数目:"<<endl;
for(i=0;i<n;i++)
{ cin>>keyong[i]; }
cout<<"剩余需求矩阵:"<<endl;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
{ cout<<need[i][j]<<" ";
if(j==n-1)
cout<<endl;
}
cout<<"各资源现有数量:"<<endl;
for(i=0;i<n;i++)
cout<<keyong[i]<<" ";
cout<<endl;
}
bool Safe() /*安全性算法*/
{ int i,j,k;
for(i=0;i<n;i++)
Work[i]=keyong[i];
for(i=0;i<m;i++)
{ FINISH[i]=false; //判断进程i是否已执行
}
for(i=0;i<m;i++)
{
if(FINISH[i]==true)
{ continue;
}
else
{ for(j=0;j<n;j++)
{ if(need[i][j]>Work[j])
{ break;
}
}
if(j==n)
{ FINISH[i]=true;
for(k=0;k<n;k++)
{ Work[k]+=fenpei[i][k]; //进程i执行完后回收资源}
p[l++]=i;
i=-1;
}
else
{
continue;
}
}
if(l==m)
{
cout<<"系统是安全的"<<endl;
cout<<"安全序列:"<<endl;
for(i=0;i<l;i++)
{
cout<<p[i];
if(i!=l-1)
{
cout<<"-->";
}
}
cout<<""<<endl;
return true;
}
}
cout<<"会发生死锁,发生死锁的进程是:"<<endl;
for(i=0;i<m;i++)
if(FINISH[i]==false)
cout<<i<<" ";
cout<<endl;
return false;
}
void jc()
{
int i,j,k,q;
i=0;
while(i<m&&FINISH[i]==false) //寻找没执行的
{
for(j=0;j<n;j++)
{
keyong[j]+=fenpei[i][j]; //回收
fenpei[i][j]=0;
}
if(Safe())
cout<<"死锁已解除"<<endl;
else
i++;
Safe();
}
}
输入
四、心得体会
通过这次实验,我了解了有关资源申请分配、检测以及避免死锁等概念,了解死锁和避免死锁的具体实施方法。死锁的解除实质上就是如何让释放资源的进程能够继续运行.为了解除死锁就要剥夺资源,
实验四 存储管理
一、实验名称
储存管理
二、实验目的
1、掌握物理内存和虚拟内存的基本概念,理解绝对地址和相对地址;
2、了解Windows中内存管理机制,掌握页式虚拟存储;
3、掌握虚拟存储管理中有关缺页处理方法等内容,巩固有关虚拟存储管理的教学内容;
4、理解内存分配原理、特别是以页面为单位的虚拟内存分配原理;
5、掌握常用的页面置换算法。
三、实验结果分析
#define MAXSIZE 20
#include <iostream.h>
void main()
{
int label=0; //标记此页是否已经装入内存
int input=0; //用于输入作业号
int worknum=0; //记录作业个数
int storesize=0; //系统分配的存储块数
int interrupt=0; //中断次数
int quence[MAXSIZE]; //队列,FIFO算法的主要数据结构
int workstep[MAXSIZE]; //用于记录作业走向
/*初始化*/
for(int i=0;i<MAXSIZE;i++)
{
quence[i]=0;
workstep[i]=0;
}
cout<<"请输入存储区块数:";
cin>>storesize;
cout<<"请输入作业走向(输入0结束):\n";
for(int j=0;j<MAXSIZE;j++)
{
cout<<"页面号:"<<j+1;
cin>>input;
workstep[j]=input;
if(input==0)
{
cout<<"输入结束!\n";
break;
}
worknum++;
}
if(workstep[0]==0)
{
cout<<"未输入任何作业,系统将退出!\n";
return;
}
cout<<"置换情况如下:\n";
for(int k=0;k<worknum;k++)
{
label=0;
/*看队列中是否有相等的页号或空位置*/
for(int l=0;l<storesize;l++)
{
/*是否有相等的页号*/
if(quence[l]==workstep[k])
{
cout<<"内存中有"<<workstep[k]<<"号页面,无须中断!\n";
label=1; //标记此页面已装入内存
break;
}
/*是否有空位置*/
if(quence[l]==0)
{
quence[l]=workstep[k];
cout<<"发生中断,但内存中有空闲区,"<<workstep[k]<<"号页面直接调入!\n";
interrupt++;
label=1;
break;
}
}
/*上述情况都不成立则调出对首,将调入页面插入对尾*/
if(label==0)
{
cout<<"发生中断,将"<<quence[0]<<"号页面调出,"<<workstep[k]<<"号装入!\n";
interrupt++;
for(int m=0;m<storesize;m++)
{
quence[m]=quence[m+1];
}
quence[storesize-1]=workstep[k];
}
}
cout<<"作业"<<worknum<<"个,"<<"中断"<<interrupt<<"次,"<<"缺页率:"<<float(interrupt)/float(worknum)*100<<"%\n";
}
四、心得体会
通过上机,我了解了许多关于操作系统的专业知识。无论是在批处理系统还是分时系统中,用户进程数一般都多于处理机数、这将导致它们互相争夺处理机。另外,系统进程也同样需要使用处理机。这就要求进程调度程序按一定的策略,动态地把处理机分配给处于就绪队列中的某一个进程,以使之执行。
这次实验课上机是我了解了许多知识,让我更加了解了处理系统,我相信我能够把处理系统用好。