题目1:基本操作命令实践
实验目的:
配合操作系统课程的学习,加深操作系统提供命令接口的功能的理解。
内容及要求:
一、验证如下命令,并且将每条命令的具体格式,记录在实验报告中。最常见的操作系统管理的一些命令。其中包括:
1、最基本、最常用的测试物理网络连通性的命令ping。ping命令用于确定本地主机是否与网络上另外一台主机相连。
2、查看DNS、IP地址、MAC地址的命令ipconfig。
3、网络信使命令net send。
4、显示计算机当前所开放的所有端口的命令netstat,并了解端口的具体意义。
5、了解net系列命令的使用。例如net view, net user, net share等。
6、路由跟踪命令tracert及pathping。
7、远程桌面连接命令mstsc。
二、借助网络,再列举一些操作系统管理命令,不少于5个并且将每条命令的具体格式,记录在实验报告中。
1.appwiz.cpl:程序和功能
2.calc:启动计算器
3.certmgr.msc:证书管理实用程序
4.charmap:启动字符映射表
5.chkdsk.exe:Chkdsk磁盘检查(管理员身份运行命令提示符)
6.cleanmgr: 打开磁盘清理工具
7.cliconfg:SQL SERVER客户端网络实用工具
8.cmstp:连接管理器配置文件安装程序
9.cmd.exe:CMD命令提示符
10.自动关机命令
Shutdown -s -t 600:表示600秒后自动关机
shutdown -a :可取消定时关机
Shutdown -r -t 600:表示600秒后自动重启
rundll32 user32.dll,LockWorkStation:表示锁定计算机
11.colorcpl:颜色管理,配置显示器和打印机等中的色彩
12.CompMgmtLauncher:计算机管理
13.compmgmt.msc:计算机管理
14.credwiz:备份或还原储存的用户名和密码
15.comexp.msc:打开系统组件服务
16.control:控制面版
17.dcomcnfg:打开系统组件服务
18.Dccw:显示颜色校准
19.devmgmt.msc:设备管理器
20.desk.cpl:屏幕分辨率
21.dfrgui:优化驱动器 Windows7→dfrg.msc:磁盘碎片整理程序
22.dialer:电话拨号程序
23.diskmgmt.msc:磁盘管理
24.dvdplay:DVD播放器
25.dxdiag:检查DirectX信息
26.eudcedit:造字程序
27.eventvwr:事件查看器
28.explorer:打开资源管理器
29.Firewall.cpl:Windows防火墙
30.FXSCOVER:传真封面编辑器
31.fsmgmt.msc:共享文件夹管理器
32.gpedit.msc:组策略
33.hdwwiz.cpl:设备管理器
34.inetcpl.cpl:Internet属性
35.intl.cpl:区域
36.iexpress:木马捆绑工具,系统自带
37.joy.cpl:游戏控制器
38.logoff:注销命令
39.lusrmgr.msc:本地用户和组
40.lpksetup:语言包安装/删除向导,安装向导会提示下载语言包
41.lusrmgr.msc:本机用户和组
42.main.cpl:鼠标属性
43.mmsys.cpl:声音
44.magnify:放大镜实用程序
45.mem.exe:显示内存使用情况(如果直接运行无效,可以先管理员身份运行命令提示符,在命令提示符里输入mem.exe>d:a.txt即可打开d盘查看a.txt,里面的就是内存使用情况了。当然什么盘什么文件名可自己决定。)
46.MdSched:Windows内存诊断程序
47.mmc:打开控制台
48.mobsync:同步命令
49.mplayer2:简易widnows mediaplayer
50.Msconfig.exe:系统配置实用程序
51.msdt:微软支持诊断工具
52.msinfo32:系统信息
53.mspaint:画图
54.Msra:Windows远程协助
55.mstsc:远程桌面连接
56.NAPCLCFG.MSC:客户端配置
57.ncpa.cpl:网络连接
58.narrator:屏幕“讲述人”
59.Netplwiz:高级用户帐户控制面板,设置登陆安全相关的选项
60.netstat : an(TC)命令检查接口
61.notepad:打开记事本
62.Nslookup:IP地址侦测器
63.odbcad32:ODBC数据源管理器
64.OptionalFeatures:打开“打开或关闭Windows功能”对话框
65.osk:打开屏幕键盘
66.perfmon.msc:计算机性能监测器
67.perfmon:计算机性能监测器
68.PowerShell:提供强大远程处理能力
69.printmanagement.msc:打印管理
70.powercfg.cpl:电源选项
71.psr:问题步骤记录器
72.Rasphone:网络连接
73.Recdisc:创建系统修复光盘
74.Resmon:资源监视器
75.Rstrui:系统还原
76.regedit.exe:注册表
77.regedt32:注册表编辑器
78.rsop.msc:组策略结果集
79.sdclt:备份状态与配置,就是查看系统是否已备份
80.secpol.msc:本地安全策略
81.services.msc:本地服务设置
82.sfc /scannow:扫描错误并复原/windows文件保护
83.sfc.exe:系统文件检查器
84.shrpubw:创建共享文件夹
85.sigverif:文件签名验证程序
86.slui:Windows激活,查看系统激活信息
87.slmgr.vbs -dlv :显示详细的许可证信息
slmgr.vbs -dli :显示许可证信息
slmgr.vbs -xpr :当前许可证截止日期
slmgr.vbs -dti :显示安装ID以进行脱机激活
slmgr.vbs -ipk :(Product Key)安装产品密钥
slmgr.vbs -ato :激活Windows
slmgr.vbs -cpky :从注册表中清除产品密钥(防止泄露引起的攻击)
slmgr.vbs -ilc :(License file)安装许可证
slmgr.vbs -upk :卸载产品密钥
slmgr.vbs -skms :(name[ort] )批量授权
88.snippingtool:截图工具,支持无规则截图
89.soundrecorder:录音机,没有录音时间的限制
90.StikyNot:便笺
91.sysdm.cpl:系统属性
92.sysedit:系统配置编辑器
93.syskey:系统加密,一旦加密就不能解开,保护系统的双重密码
94.taskmgr:任务管理器(旧版)
95.TM任务管理器(新版)
96.taskschd.msc:任务计划程序
97.timedate.cpl:日期和时间
98.UserAccountControlSettings用户账户控制设置
99.utilman:辅助工具管理器
100.wf.msc:高级安全Windows防火墙
101.WFS:Windows传真和扫描
102.wiaacmgr:扫描仪和照相机向导
103.winver:关于Windows
104.wmimgmt.msc:打开windows管理体系结构(WMI)
105.write:写字板
106.wscui.cpl:操作中心
107.wscript:windows脚本宿主设置
108.wuapp:Windows更新
题目2:Windows进程的创建与销毁
内容及要求:
① 掌握Windows进程的创建和销毁API的调用方法;编程代码,在程序中创建和销毁一个Word进程;
② 能够挂起和激活被创建进程的主线程;
③ 通过Windows进程管理器查看系统进程列表的变化。
实验指导:
①创建进程的API
BOOL CreateProcess(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
例程:
void main( VOID ){
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
// Start the child process.
if( !CreateProcess( NULL, // No module name (use command line).
"MyChildProcess", // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
0, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION structure.
) {
ErrorExit( "CreateProcess failed." );
}
// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
②销毁进程API
BOOL TerminateProcess(
HANDLE hProcess,
UINT uExitCode
);
③挂起进程的主线程API
DWORD SuspendThread(
HANDLE hThread
);
④激活进程的主线程API
DWORD ResumeThread(
HANDLE hThread
);
⑤进程查看器
#include"iostream"
#include"windows.h"
using namespacestd;
void main( VOID ){
STARTUPINFOsi;
PROCESS_INFORMATIONpi;
TCHARszCommandLine[]=TEXT("NOTEPAD");
ZeroMemory(&si, sizeof(si) );
si.cb= sizeof(si);
ZeroMemory(&pi, sizeof(pi) );
if(!CreateProcess( NULL, szCommandLine, NULL,NULL, FALSE,0,NULL, NULL,&si,&pi ) )
{
fprintf(stderr,"Createprocess Failed ");
}
int x;
while(true){
cout<<"请输入要选择的操作:\n0:销毁进程\n1:挂起进程\n2:激活进程\n3:退出\n";
cin>>x;
switch(x){
case0:
if(TerminateProcess(pi.hProcess,0))
cout<<"销毁进程成功"<<endl;
else
cout<<"销毁失败"<<endl;
break;
case1:
if(SuspendThread(pi.hThread))
cout<<"挂起进程成功"<<endl;
else
cout<<"挂起失败"<<endl;
break;
case2:
if(ResumeThread(pi.hThread))
cout<<"激活进程成功"<<endl;
else
cout<<"激活失败"<<endl;
break;
case3:
exit(0);
default:
cout<<"选项不正确"<<endl;
}
}
}
题目3 作业调度
一、实验目的
1、 对作业调度的相关内容作进一步的理解。
2、 明白作业调度的主要任务。
3、 通过编程掌握作业调度的主要算法。
二、实验内容及要求
1、对于给定的一组作业, 给出其到达时间和运行时间,例如下表所示:,
作业名 |
A |
B |
C |
D |
E |
F |
到达时间 |
0 |
2 |
5 |
5 |
12 |
15 |
服务时间 |
6 |
50 |
20 |
10 |
40 |
8 |
2、分别用先来先服务算法、短作业优先和响应比高者优先三种算法给出作业的调度顺序。
3、计算每一种算法的平均周转时间及平均带权周转时间并比较不同算法的优劣。
三、实验报告
1、程序中使用的数据结构及符号说明。
2、给出主要算法的流程图。
3、给出程序清单并附上注释。
4、给出测试数据和运行结果。
#include<iostream>
using namespace std;
#define MAX 10
struct task_struct {
charname[10]; //进程名称
intnumber; //进程编号
floatcome_time; //到达时间
floatrun_begin_time; //开始运行时间
floatrun_time; //运行时间
floatrun_end_time; //运行结束时间
int order; //运行次序
intrun_flag; //调度标志
}tasks[MAX];
int counter; //实际进程个数
int fcfs(); //先来先服务
int sjf(); //短作业优先
int hrrn(); //响应比高优先
int pinput(); //进程参数输入
int poutput(); //调度结果输出
void main() {
intoption;
pinput();
while(true){
printf("请选择调度算法(0~4):\n");
printf("1.先来先服务\n");
printf("2.短作业优先\n");
printf("3.响应比高优先\n");
printf("0.退出\n");
scanf("%d",&option);
switch(option) {
case0:
printf("运行结束。\n");
exit(0);
break;
case1:
printf("对进程按先来先服务调度。\n\n");
fcfs();
poutput();
break;
case2:
printf("对进程按短作业优先调度。\n\n");
sjf();
poutput();
break;
case3:
printf("对进程按响应比高优先调度。\n\n");
hrrn();
poutput();
break;
}
}
}
int fcfs() //先来先服务
{
floattime_temp=0;
inti;
intnumber_schedul;
time_temp=tasks[0].come_time;
for(i=0;i<counter;i++){
tasks[i].run_begin_time=time_temp;
tasks[i].run_end_time=tasks[i].run_begin_time+tasks[i].run_time;
tasks[i].run_flag=1;
time_temp=tasks[i].run_end_time;
number_schedul=i;
tasks[number_schedul].order=i+1;
}
return0;
}
int sjf(){ //短作业优先
floattemp_time=0;
inti=0,j;
intnumber_schedul,temp_counter;
floatrun_time;
run_time=tasks[i].run_time;
j=1;
while((j<counter)&&(tasks[i].come_time==tasks[j].come_time)){
if(tasks[j].run_time<tasks[i].run_time){
run_time=tasks[j].run_time;
i=j;
}
j++;
}
//查找第一个被调度的进程
//对第一个被调度的进程求相应的参数
number_schedul=i;
tasks[number_schedul].run_begin_time=tasks[number_schedul].come_time;
tasks[number_schedul].run_end_time=tasks[number_schedul].run_begin_time+tasks[number_schedul].run_time;
tasks[number_schedul].run_flag=1;
temp_time=tasks[number_schedul].run_end_time;
tasks[number_schedul].order=1;temp_counter=1;
while(temp_counter<counter) {
for(j=0;j<counter;j++) {
if((tasks[j].come_time<=temp_time)&&(!tasks[j].run_flag)) {
run_time=tasks[j].run_time;
number_schedul=j;
break;
}
}
for(j=0;j<counter;j++) {
if((tasks[j].come_time<=temp_time)&&(!tasks[j].run_flag))
if(tasks[j].run_time<run_time) {
run_time=tasks[j].run_time;
number_schedul=j;
}
}
//查找下一个被调度的进程
//对找到的下一个被调度的进程求相应的参数
tasks[number_schedul].run_begin_time=temp_time;
tasks[number_schedul].run_end_time=tasks[number_schedul].run_begin_time+tasks[number_schedul].run_time;
tasks[number_schedul].run_flag=1;
temp_time=tasks[number_schedul].run_end_time;
temp_counter++;
tasks[number_schedul].order=temp_counter;
}
return0;
}
int hrrn() /*响应比高优先*/
{
intj,number_schedul,temp_counter;
floattemp_time,respond_rate,max_respond_rate;
//第一个进程被调度
tasks[0].run_begin_time=tasks[0].come_time;
tasks[0].run_end_time=tasks[0].run_begin_time+tasks[0].run_time;
temp_time=tasks[0].run_end_time;
tasks[0].run_flag=1;
tasks[0].order=1;
temp_counter=1;//调度其他进程
while(temp_counter<counter){
max_respond_rate=0;
for(j=1;j<counter;j++){
if((tasks[j].come_time<=temp_time)&&(!tasks[j].run_flag))
{
respond_rate=(temp_time-tasks[j].come_time)/tasks[j].run_time;
if(respond_rate>max_respond_rate){
max_respond_rate=respond_rate;
number_schedul=j;
}
}
}
//找响应比高的进程
tasks[number_schedul].run_begin_time=temp_time;
tasks[number_schedul].run_end_time=tasks[number_schedul].run_begin_time+tasks[number_schedul].run_time;
temp_time=tasks[number_schedul].run_end_time;
tasks[number_schedul].run_flag=1;
temp_counter+=1;
tasks[number_schedul].order=temp_counter;
}
return0;
}
int pinput() //进程参数输入
{
inti;
printf("请输入进程的数量:\n");
scanf("%d",&counter);
for(i=0;i<counter;i++)
{
printf("请输入第%d个进程信息 :\n",i+1);
printf("请输入进程名字:\n");
scanf("%s",tasks[i].name);
printf("请输入进程编号:\n");
scanf("%d",&tasks[i].number);
printf("请输入进程到达时间:\n");
scanf("%f",&tasks[i].come_time);
printf("请输入进程运行时间:\n");
scanf("%f",&tasks[i].run_time);
tasks[i].run_begin_time=0;
tasks[i].run_end_time=0;
tasks[i].order=0;
tasks[i].run_flag=0;
}
return0;
}
int poutput() //调度结果输出
{
inti;
floatturn_round_time=0,f1,w=0;
printf("进程名字 进程编号 到达时间 运行时间 开始时间 结束时间 运行次序 周转时间\n");
for(i=0;i<counter;i++){
f1=tasks[i].run_end_time-tasks[i].come_time;
turn_round_time+=f1;
w+=(f1/tasks[i].run_time);
printf("%s, %d, %5.3f, %5.3f, %5.3f, %5.3f, %d, %d,%5.3f\n",tasks[i].name,tasks[i].number,tasks[i].come_time,tasks[i].run_time,tasks[i].run_begin_time,tasks[i].run_end_time,tasks[i].order,f1);
}
printf("平均周转时间=%5.2f\n",turn_round_time/counter);
printf("平均带权周转时间=%5.2f\n",w/counter);
return0;
}
题目4 基于优先数的时间片轮转调度算法调度处理器
一、实验目的
在采用多道程序设计的系统中,同时处于就绪态的进程往往有多个,当就绪态的进程数大于处理器的个数时,就需按照某种策略进行分配处理器。本次设计模拟在单处理器情况下采用基于优先数的时间片轮转调度算法进行处理器调度,加深了解处理器调度工作过程。
二、实验内容及要求
1、设计一个程序实现基于优先数的时间片轮转调度算法调度处理器。
2、假定系统有5个进程,每个进程用一个进程控制块PCB来代表,进程控制块的结构如下图1.2所示:
进程名 |
指针 |
到达时间 |
要求运行时间 |
已运行时间 |
优先数 |
进程状态 |
图1
其中:
进程名:作为进程的标识。
指针:进程按顺序排成循环链表,用指针指出下一个进程的进程控制块首地址,最后一个进程中的指针指出第一个进程的进程控制块首地址。
要求运行时间:假设进程需要运行的单位时间数。
已运行时间:假设进程已经运行的单位时间数,初值为0。
状态:可假设有两种状态,就绪状态和结束状态。进程的初始状态都为就绪状态。
3、每次运行所设计的处理器调度程序调度进程之前,为每个进程任意确定它的要求运行时间。
4、此程序是模拟处理器调度,因此,被选中的进程并不实际启动运行,而是执行
已运行时间+1
来模拟进程的一次运行,表示进程已经运行过一个单位时间。
.5、在所设计的程序中应有显示或打印语句,能显示或打印每次被选中的进程名以及运行一次后进程队列的变化。
6、为进程任意确定要求运行时间,运行所设计的处理器调度程序,显示或打印逐次被选中进程的进程名以及进程控制块的动态变化过程。
7、设有一个就绪队列,就绪进程按优先数(优先数范围0-100)由小到大排列(优先数越小,级别越高)。当某一进程运行完一个时间片后,其优先级应下调(如优先数加2或3)。
8、例如一组进程如下表:
进程名 |
A |
B |
C |
D |
E |
F |
G |
H |
J |
K |
L |
M |
到达时间 |
0 |
1 |
2 |
3 |
6 |
8 |
12 |
12 |
12 |
18 |
25 |
25 |
服务时间 |
6 |
4 |
10 |
5 |
1 |
2 |
5 |
10 |
4 |
3 |
15 |
8 |
三、实验报告
1、程序中使用的数据结构及符号说明。
2、给出主要算法的流程图
3、给出程序清单并附上注释
4、打印程序运行时的初值和运行结果。(运行一个进程输出一次结果)
//按优先数调度算法实现处理器调度的程序 #include"stdio.h"#include"string.h" #definenum 5//假定系统中进程个数为5structPCB{ charID;//进程名 intruntime;//要求运行时间 intpri;//优先数 char state; //状态,R-就绪,F-结束 }; structPCB pcblist[num];//定义进程控制块数组 voidinit()//PCB初始化子程序{ int i; for(i=0;i<num;i++) { printf("PCB[%d]:进程名 优先数 要求运行时间 \n",i+1);//为每个进程任意指定pri和runtime scanf("%s%d%d",&pcblist[i].ID,&pcblist[i].pri,&pcblist[i].runtime); pcblist[i].state='R';//进程初始状态均为就绪 getchar();//接收回车符 } }intmax_pri_process()//确定最大优先级进程子程序{ int max=-100;//max为最大优先数,初始化为-100 inti; intkey; for(i=0;i<num;i++) { if(pcblist[i].state=='r')//r为辅助状态标志,表示正在运行 return-1;//返回-1 else if(max<pcblist[i].pri&&pcblist[i].state=='R')//从就绪进程中选取优先数最大的进程 { max=pcblist[i].pri;//max存放每次循环中的最大优先数 key=i;//将进程号赋给key } } if(pcblist[key].state=='F')//具有最大优先数的进程若已运行完毕 return-1;//则返回-1 else//否则 returnkey;//将key作为返回值返回} voidshow()//显示子程序{ inti; printf("\n 进程名 优先数 要求运行时间 状态 \n"); printf("-------------------------------------------------\n"); for(i=0;i<num;i++)//依次显示每个进程的名、优先数、要求运行时间和状态 { printf("%s%6d%8d%s\n",&pcblist[i].ID,pcblist[i].pri,pcblist[i].runtime,&pcblist[i].state); } printf(" pressany key to continue...\n");} voidrun()//进程运行子程序{ inti,j; intt=0;//t为运行次数 for(j=0;j<num;j++) { t+=pcblist[j].runtime;}//运行次数即为各个进程运行时间之和 printf("\nbeforerun,the conditon is:\n"); show();//调用show()子程序显示运行前PCB的情况 getchar();//等待输入回车符 for(j=0;j<t;j++) { while(max_pri_process()!=-1)//具有最大优先数的进程没有运行完,让其运行 { pcblist[max_pri_process()].state='r';//将其状态置为r,表示其正在运行 } for(i=0;i<num;i++) { if(pcblist[i].state=='r') { pcblist[i].pri-=1;//将当前运行进程的优先数减1 pcblist[i].runtime--;//要求运行时间减1 { if(pcblist[i].runtime==0) pcblist[i].state='F';//运行完则将该进程状态置为结束 else pcblist[i].state='R';//未运行完将其状态置为就绪 } show();//显示每次运行后各PCB的情况 getchar();//等待回车进入下一次运行 } } }}voidmain()//按动态优先数调度主程序{ init();//初始化各个进程PCB run();//进程调度模拟}
题目5 银行家算法
一、实验目的
1、 对死锁避免中的银行家算法作进一步理解。
2、 加深理解死锁的概念。
3、 加深理解安全序列和安全状态的概念。
4、 通过编程,掌握银行家算法分配资源的一步步实现过程。
二、实验内容及要求
1、给出系统可用资源向量(例如:系统可用资源=(5,3,8,2,10))。
2、若干进程最大需求矩阵如下表所示:
3、采用时间片轮转法调度进程。
4、进程执行时提出资源请求(可利用随机数给出或从键盘输入)。
5、判断资源是否可以安全分配,要求进程每提出一个资源请求,都要进行安全判断并给出安全序列,否则给出提示。
三、实验报告
1、程序中使用的数据结构及符号说明。
2、给出主要算法的流程图。
3、给出程序清单并附上注释。
4、给出测试数据和运行结果。
#include<iostream>
usingnamespace std;
#defineMAXPROCESS 50 //最大进程数
#defineMAXRESOURCE 100 //最大资源数
intAvailable[MAXRESOURCE]; //可用资源数组
intMax[MAXPROCESS][MAXRESOURCE]; //最大需求矩阵
intAllocation[MAXPROCESS][MAXRESOURCE]; //分配矩阵
intNeed[MAXPROCESS][MAXRESOURCE]; //需求矩阵
int Request[MAXPROCESS][MAXRESOURCE]; //进程需要资源数
boolFinish[MAXPROCESS]; //系统是否有足够的资源分配
intp[MAXPROCESS]; //记录序列
intm,n; //m个进程,n个资源
voidInit(){ //初始化算法
int i,j;
cout<<"请输入进程的数目:";
cin>>m;
cout<<"请输入资源种类的数目:";
cin>>n;
cout<<"请输入每个进程最大需求资源数矩阵:"<<endl;
for(i=0;i<m;i++){
for(j=0;j<n;j++){
cin>>Max[i][j];
}
}
cout<<"请输入每个进程已分配的各资源数矩阵:"<<endl;
for(i=0;i<m;i++){ //判断输入的资源数是否合理
for(j=0;j<n;j++){
cin>>Allocation[i][j];
Need[i][j]=Max[i][j]-Allocation[i][j];//各进程尚需要的资源数
if(Need[i][j]<0){
cout<<"您输入的第"<<i+1<<"个进程的第"<<j+1<<"个资源数有错误,请重新输入:"<<endl;
j--;
continue;
}
}
}
cout<<"请输入可利用资源向量矩阵:"<<endl;
for(i=0;i<n;i++){
cin>>Available[i];
}
}
boolSafe(){ //判断安全函数
inti,j,k,l=0;
int Work[MAXRESOURCE]; //系统可提供给进程继续运行所需要的各类资源数目
for(i=0;i<n;i++)
Work[i]=Available[i];
for(i=0;i<m;i++){
Finish[i]=false;
}
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]+=Allocation[i][k];
}
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;
returntrue;
}
}
cout<<"此时系统是不安全的"<<endl;
returnfalse;
}
voidBank() /*银行家算法*/
{
int i,cusneed;
char again;
while(1)
{
cout<<"请输入要申请资源的进程号(第1个进程号为0,依次类推)"<<endl;
cin>>cusneed;
cout<<"请输入进程的各资源需求矩阵"<<endl;
for(i=0;i<n;i++)
{
cin>>Request[cusneed][i];
}
for(i=0;i<n;i++)
{
if(Request[cusneed][i]>Need[cusneed][i])
{
cout<<"您输入的请求数超过进程的需求量!请重新输入!"<<endl;
continue;
}
if(Request[cusneed][i]>Available[i])
{
cout<<"您输入的请求数超过系统拥有的资源数!请重新输入!"<<endl;
continue;
}
}
for(i=0;i<n;i++) //假如系统将资源分配给p[i]
{
Available[i]-=Request[cusneed][i];
Allocation[cusneed][i]+=Request[cusneed][i];
Need[cusneed][i]-=Request[cusneed][i];
}
if(Safe()) //执行判断是否安全函数
{
cout<<"同意分配请求!"<<endl;
}
else
{
cout<<"您的请求被拒绝!"<<endl;
for(i=0;i<n;i++) //不安全的,回复资源分配表
{
Available[i]+=Request[cusneed][i];
Allocation[cusneed][i]-=Request[cusneed][i];
Need[cusneed][i]+=Request[cusneed][i];
}
}
for(i=0;i<m;i++)
{
Finish[i]=false;
}
cout<<"您还想再次请求分配吗?是请按y/Y,否请按其它键"<<endl;
cin>>again;
if(again=='y'||again=='Y')
{
continue;
}
break;
}
}
voidmain()
{
Init();
Safe();
Bank();
}
题目6 内存管理
一、实验目的
1、 对内存管理的相关内容做进一步的理解。
2、 了解内存管理的主要任务。
3、 了解内存管理任务的主要实现方法。
4、 通过编程加深理解内存的分配、回收等主要算法的原理。
二、实验内容及要求
1、在该实验中,采用可变分区方式完成对存储空间的管理(即存储空间的分配与回收工作)。
2、设计用来记录主存使用情况的数据结构:已分区表和空闲分区表。
3、在设计好的数据结构上设计一个主存分配算法,要求实现的基本功能操作有:寻找空闲分区,空闲分区表的修改,已分区表的修改。
4、在设计好的数据结构上设计一个主存回收算法。其中,若回收的分区有上邻空闲分区和(或)下邻空闲分区,要求合并为一个空闲分区登记在空闲分区表的一个表项里。
三、实验报告
1、程序中使用的数据结构及符号说明。
2、给出主要算法的流程图。
3、给出程序清单并附上注释。
4、给出测试数据和运行结果,要求系统每进行一次分配或回收,都要给出内存映像图或已分配表及未分配表以观察内存的变化。
程序代码
#include<iostream>
#include<vector>
#include<fstream>
#include<sstream>
#include<string>
usingnamespace std;
typedefstruct node
{
intID; //分区ID
struct node *next; //指向下个分区的指针
float beginAddress; //分区起始地址
float length; //分区长度
int state; //分区状态
}FQ;
FQ*First=(FQ*)malloc(sizeof(FQ)); //头指针
intFQCount=0; //分区个数
intmaxID=0;
voiddisplay() //打印内存初始分配状态
{
FQ*fqBegin=First->next;
cout<<"分区ID\t分区开始地址\t分区长度\t分区状态\n";
while(fqBegin!=NULL)
{
cout<<fqBegin->ID<<"\t"<<fqBegin->beginAddress<<"\t\t"<<fqBegin->length<<"\t\t"<<fqBegin->state<<endl;
fqBegin=fqBegin->next;
}
}
voidDistribute(float len) //分配内存函数
{
FQ*temp=(FQ*)malloc(sizeof(FQ));
temp=First; //当前指针指向头指针
while(!(temp->next->state==0&&temp->next->length>=len)) //此分区的状态为占用状态或者分区长度小于需要的长度
{
temp=temp->next; //考虑下一个分区
}
temp=temp->next;
// 修改分区表
FQ*fq1=(FQ*)malloc(sizeof(FQ));
fq1->ID=++maxID;
fq1->next=temp->next;
fq1->beginAddress=temp->beginAddress+len;
fq1->length=temp->length-len;
fq1->state=0;
temp->next=fq1;
temp->length=len;
temp->state=1;
cout<<"分配内存后的内存状态:"<<endl;
display();
}
voidrecover(int id) //回收内存函数
{
if (id>maxID) //判断想要回收的分区是否合理
{
cout<<"输入的id过大,没有与之匹配的分区"<<endl;
}
else{
FQ*temp=(FQ*)malloc(sizeof(FQ));
temp=First; //当前指针指向头指针
while(!(temp->next->ID==id)) //寻找要回收的分区的id
{
temp=temp->next;
}
if(temp->state==0) //分区状态为空闲时
{
if(temp->next->next==NULL)
{
temp->next=NULL;
temp->length=temp->length+temp->next->length;
//若回收的分区有上邻空闲分区和(或)下邻空闲分区,要求合并为一个空闲分区登记在空闲分区表的一个表项里
}
elseif(temp->next->next->state==1)
{
temp->next=temp->next->next;
temp->length=temp->length+temp->next->length;
//若回收的分区有上邻空闲分区和(或)下邻空闲分区,要求合并为一个空闲分区登记在空闲分区表的一个表项里
}
else
{
temp->length=temp->length+temp->next->length+temp->next->next->length;
//若回收的分区有上邻空闲分区和(或)下邻空闲分区,要求合并为一个空闲分区登记在空闲分区表的一个表项里
temp->next=temp->next->next->next;
}
}
else //分区被占用时
{
if(temp->next->next==NULL||temp->next->next->state==1)
{
temp->next->state=0; //分区状态改为空闲
}
else
{
temp->next->length=temp->next->length+temp->next->next->length;
//若回收的分区有上邻空闲分区和(或)下邻空闲分区,要求合并为一个空闲分区登记在空闲分区表的一个表项里
temp->next->next=temp->next->next->next;
temp->next->state=0; //分区状态改为空闲
}
}
cout<<"回收内存后的内存状态:"<<endl;
display();
}
}
int main() //主函数
{
//初始化内存分区状态
fstreamfile;
file.open("start.txt",ios_base::in|ios_base::out|ios_base::app); //读写input.txt文件,读入最初的内存分配状态
strings0;
getline(file,s0); //从输入流读取一行到s0
istringstream sin(s0); //从s0中读取单个字符
sin>>FQCount; //将sin向右位移6位
FQ*temp=(FQ*)malloc(sizeof(FQ)); //定义当前指针
temp=First;
for(string s;getline(file,s);) //将文件中的分区起始地址,分区长度及分区状态读入程序
{
FQ*fq=(FQ*)malloc(sizeof(FQ));
istringstreamsin(s);
sin>>fq->beginAddress;
sin>>fq->length;
sin>>fq->state;
fq->ID=++maxID;
fq->next=NULL;
temp->next=fq;
temp=fq;
}
cout<<"最初的内存分配状态:"<<endl;
display();
while(1)
{
cout<<"请选择要进行的操作:\n1.请求分配内存 \n2.请求回收内存 \n3.退出\n";
intchoice;
cin>>choice;
switch(choice){
case1:
cout<<"请求分配内存\n";
cout<<"请输入要分配的内存的长度:";
intlen;
cin>>len;
Distribute(len);
break;
case2:
cout<<"请求回收内存\n";
cout<<"请输入要回收的内存的ID:";
intID;
cin>>ID;
recover(ID);
break;
case3:
exit(0);
break;
default:
cout<<"输入有误!请重新输入!\n";
continue;
}
}
return0;
}
内存分区初始状态文件start.txt
6
0 500 1
501 1000 0
1501 2000 1
3501 2500 0
6001 4000 1
10001 5000 0
题目7 页面置换
一、实验目的
1、对页面置换做进一步的理解。
2、了解页面置换的任务。
3、通过编程掌握页面置换算法及缺页率。
4、了解Belady现象和抖动现象。
二、实验内容及要求
1、任意给出一组页面访问顺序(如页面走向是1、2、5、7、5、7、1、4、3、5、6、4、3、2、1、5、2)。
2、分配给该作业一定的物理块(如3块、4块等)。
3、利用某几种页面置换算法模拟页面置换过程并计算其缺页率并分析结果。
4、通过给出特殊的页面访问顺序,分配不同的物理块,利用FIFO算法计算其缺页率,进一步理解Belady现象。
三、实验报告
1、程序中使用的数据结构及符号说明。
2、给出主要算法的流程图。
3、给出程序清单并附上注释。
4、给出测试数据和运行结果,要求系统每进行一次页面置换,都要给出换进和换出的页面号。
5、通过测试数据观察Belady现象。
#include<stdlib.h>
#include<iostream.h>
#include<time.h>
void rand(intn,int p[])//这函数是产生n个1~10的随机数放到p[]数组里面
{
intSTART=1;
intEND=10;
intv;
inti;
inta;
srand(time(NULL));
for(i=0;i<n;i++)
{
v=rand()%(END-START+1)+START;
p[i]=v;
cout<<v;
}
}
struct Pro {
int num,time; //num存放具体的内容,time在不同算法里面有不同的意义
};
//它们是物理块和页面的数据结构
int Input(intm,int N,Pro *p,Pro *page)//完成p[]数组和page[]的初始化工作
{
//p[]数组是存放页面的空间,m是页面的长度
//page[]是可以使用的物理块,N是物理块的大小
cout<<endl<<"请输入各页面号"<<endl;
int *p2=newint[m];
rand(m,p2);
for(inti=0;i<m;i++) {
p[i].num=p2[i];
p[i].time=0;
}
for(i=0;i<N;i++){ //初试化页面基本情况
page[i].num=0;
page[i].time=N+2-i;
}
returnm;
}
int Search(inte,Pro *page,int N)//算法里面都要用到它。
{
//它是找e页是否在page物理块中,N是物理块的大小
for(inti=0;i<N;i++)
if(e==page[i].num)
returni;//如果找到,就返回在物理块中的位置给Search
return-1;//找不到,就返回-1
}
int Max(Pro*page,int N)//LRU算法用到的
{
//找出在page块中,time最大的值和位置,同时位置返回 //time最大,就代表了最久没被使用的数
inte=page[0].time,i=0;
intk=0;
while(i<N)//找出离现在时间最长的页面
{
if(e<page[i].time){
k=i;
}
i++;
}
cout<<"换出页面:"<<page[i].num<<endl;
returnk;
}
int Compfu(Pro*page,int i,int t,Pro p[],int m)//OPT算法用到的
{
//找出如果page[t]要等于p,并且zai p[i]~p[m]这个区间内,走的次数,最大的数
int count=0;//count是保存走的步数
for(intj=i;j<m;j++)
{
if(page[t].num==p[j].num)
break;//如果相等,跳出循环
else
count++;//不等就步数加1
}
returncount;
}
int Min(Propage[],int N)//LFU算法用到的
{
//page[]是可以使用的物理块,N是物理块的大小 //找到出现次数最小的的数,并把位置返回
intk=0;
intmin=page[0].time;
for(inti=0;i<N;i++)
{
if(min>page[i].time)
k=i;
}
returnk;
}
void FIFO(Prop[],Pro page[],int m,int N)//p[]数组是存放页面的空间,m是页面的长度
{
//page[]是可以使用的物理块,N是物理块的大小
float n=0;//n用来保存缺页的次数
int i=0;//i是循环变量,它是表示走到页面的位置
int t=0;//t是用来表示物理块走到的位置
cout<<"页面置换情况:"<<endl;
for(i=0;i<m;i++)
{
if(Search(p[i].num,page,N)>=0)
continue;//找到相同的页面,就跳到下一次循环,不做处理。
else//在找不到的时候,通过t=t%N,求出这次来替换物理块的位置
{
cout<<"需要换进页面"<<p[i].num<<endl;
t=t%N;
cout<<"需要换出页面"<<p[t].num<<endl;
n++;//缺页数加1
page[t].num=p[i].num;
t++;//位置加1
}
}
cout<<"缺页次数:"<<n<<" 缺页率:"<<n/m<<" 命中率:"<<1-n/m<<endl;
}
void LFU(Prop[],Pro page[],int m,int N)//p[]数组是存放页面的空间,m是页面的长度
{
//page[]是可以使用的物理块,N是物理块的大小,
floatn=0;
inti=0;
intt=0;
for(i=0;i<N;i++)
page[i].time=0;
cout<<"页面置换情况: "<<endl;
for(i=0;i<m;i++)
{
if(Search(p[i].num,page,N)>=0)
{
page[i].time++;//找到相同的页面,time加1
continue;//
}
else
{
//找出使用最少的页面进行调换
t=Min(page,N);//找到出现次数最小的的数,并把位置返回t
page[t].num=p[i].num;
page[t].time=0;//该页time清零
n++;//缺页数加1
}
}
cout<<"缺页次数:"<<n<<" 缺页率:"<<n/m<<" 命中率:"<<1-n/m<<endl;
}
void OPT(Prop[],Pro page[],int m,int N)//p[]数组是存放页面的空间,m是页面的长度
{
//page[]是可以使用的物理块,N是物理块的大小
float n=0;//n用来保存缺页的次数
int i=0;//i是循环变量,它是表示走到页面的位置。
int t=0; //t是用来表示物理块走到的位置
while(i<m)
{
if(Search(p[i].num,page,N)>=0)
i++;//如果找到了,就不做处理。
else//如果找不到
{
int temp=0,cn;//cn用来保存离后面最远的数
for(t=0;t<N;t++)//对物理块里面的每个数进行遍历
{
if(temp<Compfu(page,i,t,p,m))//temp用来保存
{
//page[t]= p[i]~p[m]这个区间内,走的次数,最大的数
temp=Compfu(page,i,t,p,m);
cn=t;
}
}
page[cn]=p[i];//把当前的值放要发生要走最远的数,也就最不可能最近出现的数
n=n+1;//缺页数加1
i++;//跳到下一次循环
}
}
cout<<"缺页次数:"<<n<<" 缺页率:"<<n/m<<" 命中率:"<<1-n/m<<endl;
}
void LRU(Prop[],Pro page[],int m,int N)//p[]数组是存放页面的空间,m是页面的长度
{
//page[]是可以使用的物理块,N是物理块的大小
float n=0;//n用来保存缺页的次数
int i=0;//i是循环变量,它是表示走到页面的位置。
int t=0; //t是用来表示物理块走到的位置
cout<<"页面置换情况:"<<endl;
while(i<m)
{
int k;
k=t=Search(p[i].num,page,N);
if(t>=0){
page[t].time=0;//如果找到,就要把当前的page[t].time次数清零
}
else//找不到的时候,发生缺页
{
cout<<"发生缺页,需换进页:"<<page[t].num<<endl;
n++; //缺页数加1
t=Max(page,N);//找出page物理块里面,最久没被时候的数
//同时把最久没被时候的数在物理块里的位置传给t
page[t].num=p[i].num;//最久没被使用的是被现在的数代替
page[t].time=0;//同时清零
}
for(intj=0;j<N;j++)//把缺页以外的数,把它没被使用的次数加1
{
if(j==t)
continue;
page[t].time++;
}
i++;//跳到下一次循环
}
cout<<"缺页次数:"<<n<<" 缺页率:"<<n/m<<" 命中率:"<<1-n/m<<endl;
}
void main()
{
int m=0,t=0,N=0;
cout<<"请输入总页数:";
cin>>m;
Pro *p=new Pro[m];//p是用来放页面的地方
cout<<"请输入物理块数:"<<endl;
cin>>N;
Pro *page=new Pro[N];//page是放物理块的地方
int c;
float n=0;
Input(m,N,p,page);//m是页面的总长,N是物理块的长度
cout<<""<<endl;
while(true){
cout<<"1:FIFO页面置换"<<endl;
cout<<"2:LRU页面置换"<<endl;
cout<<"3:OPT页面置换"<<endl;
cout<<"4:LFU页面置换"<<endl;
cout<<"0:结束"<<endl;
cin>>c;
switch(c){
case1:
FIFO(p,page,m,N);
break;
case2:
LRU(p,page,m,N);
break;
case3:
OPT(p,page,m,N);
break;
case4:
LFU(p,page,m,N);
break;
case0:
exit(0);
default:
cout<<"没有与输入相匹配的操作,请重新输入"<<endl;
}
}
}
题目8 磁盘调度
一、实验目的
1、对磁盘调度的相关知识作进一步的了解,明确磁盘调度的原理。
2、加深理解磁盘调度的主要任务。
3、通过编程,掌握磁盘调度的主要算法。
二、实验内容和要求
1、对于如下给定的一组磁盘访问进行调度:
请求服务到达 |
A |
B |
C |
D |
E |
F |
G |
H |
I |
J |
K |
访问的磁道号 |
30 |
50 |
100 |
180 |
20 |
90 |
150 |
70 |
80 |
10 |
160 |
2、要求分别采用先来先服务、最短寻道优先以及电梯调度方法进行调度。
3、要求给出每种算法中磁盘访问的顺序,计算出平均移动道数。
4、假定当前读写头在90号,向磁道号增加的方向移动。
三、实验报告
1、程序中使用的数据结构及符号说明。
2、给出主要算法的流程图。
3、给出程序清单并附上注释。
4、给出测试数据和运行结果。
#include "iostream.h"
#include "math.h"
//定义服务作业结构体
struct jop{
charname;
intnum;
};
//初始化服务作业
void intput_Rec(struct jop *p){
cin>>p->name;
cin>>p->num;
}
//交换服务作业算法
void swap_Rec(struct jop *p1,struct jop*p2){
structjop x;
x=*p1;
*p1=*p2;
*p2=x;
}
//输出服务作业算法
void put_Rec(struct jop *p){
cout<<p->name<<'\t';
cout<<p->num<<endl;
}
//先来先服务调度算法
void FCFS(int mid,struct jop a[]){
cout<<"先来先服务调度算法"<<endl;
inti;
intsum=0;
//按服务到达时间顺序访问并计算
for(i=0;i<11;i++){
mid=abs(a[i].num-mid);
sum+=mid;
cout<<a[i].name<<" ";
cout<<a[i].num<<" ";
cout<<mid<<""<<endl; //需要移动的磁道数
}
cout<<"平均移动道数"<<(double)sum/11<<endl;
}
//最短寻道优先算法
void SSTF(int mid,struct jop a[]){
cout<<"最短寻道优先算法"<<endl;
intsum=0;
inti;
for(i=0;i<11;i++){
if(a[i].num==mid){
int flag=0;
ints=1;
intk;// 下标
k=i;
cout<<a[k].name<<" ";
cout<<a[k].num<<" ";
cout<<"0"<<endl;
for(s=1;s<11;s++){
if(flag=1){
//第k-1个作业需要移动的磁道数大于k+s需要移动的磁道数
if(abs(mid-a[k-1].num)>=abs(mid-a[k+s].num)){
sum=sum+abs(a[k+s].num-mid);
//输出k+s的作业信息
cout<<a[k+s].name<<" ";
cout<<a[k+s].num<<" ";
cout<<abs(mid-a[k+s].num)<<endl;
//将磁道数比较值置为k+s的磁道号
mid=a[k+s].num;
flag=1;
k=k+s;
}
//第k-1个作业需要移动的磁道数小于k+s需要移动的磁道数
if(abs(mid-a[k-1].num)<abs(mid-a[k+s].num)){
sum=sum+abs(a[k-1].num-mid);
//输出k-1的作业信息
cout<<a[k-1].name<<" ";
cout<<a[k-1].num<<" ";
cout<<abs(mid-a[k-1].num)<<endl;
//将磁道数比较值置为k-1的磁道号
mid=a[k-1].num;
flag=0;
k=k-1;
}
}
if(flag=0){
//第k-s个作业需要移动的磁道数大于k+1需要移动的磁道数
if(abs(mid-a[k-s].num)>=abs(mid-a[k+1].num)){
sum=sum+abs(a[k+1].num-mid);
//输出k+1的作业信息
cout<<a[k+1].name<<" ";
cout<<a[k+1].num<<" ";
cout<<abs(mid-a[k+1].num)<<endl;
//将磁道数比较值置为k+1的磁道号
mid=a[k+1].num;
flag=1;
k=k+1;
}
//第k-s个作业需要移动的磁道数小于k+1需要移动的磁道数
if(abs(mid-a[k-s].num)<abs(mid-a[k+1].num)){
sum=sum+abs(a[k-s].num-mid);
//输出k-s的作业信息
cout<<a[k-s].name<<" ";
cout<<a[k-s].num<<" ";
cout<<abs(mid-a[k-s].num)<<endl;
//将磁道数比较值置为k-s的磁道号
mid=a[k-s].num;
flag=0;
k=k-s;
}
}
if(k<=0||k>=11)break;
}
if(k<=1){
for(k=k+s+1;k<11;k++){
sum=sum+abs(a[k].num-mid);
cout<<a[k].name<<" ";
cout<<a[k].num<<" ";
cout<<abs(a[k].num-mid)<<endl;
mid=a[k].num;
}
}
break;
}
}
cout<<"平均移动道数"<<(double)sum/11<<endl;
}
//电梯调度方法算法
void SCAN(int mid,struct jop a[]){
cout<<"电梯调度方法算法"<<endl;
intsum=0;
for(inti=0;i<11;i++){
//从中间向外访问磁道号
if(a[i].num>=mid)
{
intk;
//从中间访问到磁道号最大值
for(k=i;k<11;k++){
sum+=a[k].num-mid;
cout<<a[k].name<<" ";
cout<<a[k].num<<" ";
cout<<a[k].num-mid<<endl;
mid=a[k].num;
}
//返回中间,再从中间访问到磁道号最小值
for(k=i-1;k>0;k--){
sum+=mid-a[k].num;
cout<<a[k].name<<" ";
cout<<a[k].num<<" ";
cout<<mid-a[k].num<<endl;
mid=a[k].num;
}
cout<<"平均移动道数"<<(double)sum/11<<endl;
break;
}
}
}
void main(){
inti=0,j=0;
intmid=90; //最短寻到优先算法初始判断的磁道号
intsum=0;
structjop *p1,a[11];
cout<<"请输入"<<endl;
cout<<"服务名称\t磁道号"<<endl;
for(p1=a;p1<a+11;p1++){
intput_Rec(p1);
}
FCFS(mid,a);
//为SCAN,SSTF作准备
for(i=0;i<11;i++){
for(j=i+1;j<11;j++){
if(a[i].num>a[j].num)
swap_Rec(&a[i],&a[j]);
}
}
SSTF(mid,a);
SCAN(mid,a);
}
今天的文章编写一个windows窗体程序_大一windows实验报告「建议收藏」分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/69332.html