操作系统实验及代码(全)
题目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;elsecout<<"销毁失败"<<endl;break;case1:if(SuspendThread(pi.hThread))cout<<"挂起进程成功"<<endl;elsecout<<"挂起失败"<<endl;break;case2:if(ResumeThread(pi.hThread))cout<<"激活进程成功"<<endl;elsecout<<"激活失败"<<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//假定系统中进程个数为5
structPCB
{ 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和runtimescanf("%s%d%d",&pcblist[i].ID,&pcblist[i].pri,&pcblist[i].runtime);pcblist[i].state='R';//进程初始状态均为就绪getchar();//接收回车符}
}
intmax_pri_process()//确定最大优先级进程子程序
{ int max=-100;//max为最大优先数,初始化为-100inti;intkey; for(i=0;i<num;i++) {if(pcblist[i].state=='r')//r为辅助状态标志,表示正在运行return-1;//返回-1elseif(max<pcblist[i].pri&&pcblist[i].state=='R')//从就绪进程中选取优先数最大的进程{ max=pcblist[i].pri;//max存放每次循环中的最大优先数key=i;//将进程号赋给key } } if(pcblist[key].state=='F')//具有最大优先数的进程若已运行完毕return-1;//则返回-1else//否则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;//将当前运行进程的优先数减1pcblist[i].runtime--;//要求运行时间减1{if(pcblist[i].runtime==0) pcblist[i].state='F';//运行完则将该进程状态置为结束else pcblist[i].state='R';//未运行完将其状态置为就绪}show();//显示每次运行后各PCB的情况getchar();//等待回车进入下一次运行}}}
}
voidmain()//按动态优先数调度主程序
{ init();//初始化各个进程PCBrun();//进程调度模拟
}
题目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; //分区IDstruct 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); //从输入流读取一行到s0istringstream 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;//如果找到,就返回在物理块中的位置给Searchreturn-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;//如果相等,跳出循环elsecount++;//不等就步数加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);
}
操作系统实验及代码(全)相关推荐
- 西电软工操作系统实验:编译Ubuntu18.04新内核并添加系统调用(含代码以及详细分析)
西电软工操作系统实验一:编译Linux内核 目录 (一)前言 (二)实验内容 (三)实验环境 (四)实验过程 4.1安装虚拟机 4.2虚拟机换源 4.3 添加系统调用内核 4.4 下载编译所需的软件依 ...
- 操作系统实验报告 实验1 VMware虚拟机配置与linux基本命令(答案全)
实验1 VMware虚拟机配置与linux基本命令 (1) 实验目的 (2) 实验要求: (3) 实验步骤 1.1 Linux Ubuntu的安装.创建新的虚拟机VMWare 实验1.2 linux系 ...
- 操作系统实验报告11:ucore Lab 2
ucore实验报告2 实验内容 uCore Lab 2:物理内存管理 (1) 编译运行 uCore Lab 2 的工程代码: (2) 完成 uCore Lab 2 练习 1-3 的编程作业: (3) ...
- 操作系统实验报告8:进程间通信—消息机制
操作系统实验报告8 实验内容 实验内容1:进程间通信-消息机制 编译运行课件 Lecture 09 例程代码: Algorithms 9-1 ~ 9-2. 修改代码,观察在 msgsnd 和 msgr ...
- 操作系统实验报告6:进程间通信—共享内存
操作系统实验报告6 实验内容 实验内容:进程间通信-共享内存. (1).验证:编译运行课件 Lecture 08 例程代码: Linux 系统调用示例 reader-writer 问题:Algorit ...
- 操作系统实验一到实验九合集(哈工大李治军)
操作系统实验 作者寄语 操作系统实验的学习是一个循序渐进的过程,初次看linux-0.11中的代码,看着满屏的汇编语言,确实头疼.但通过学习赵炯博士的Linux内核0.11完全注释,结合着王爽老师的汇 ...
- 操作系统实验四 进程运行轨迹的跟踪与统计(哈工大李治军)
实验4 进程运行轨迹的跟踪与统计 实验目的 掌握 Linux 下的多进程编程技术: 通过对进程运行轨迹的跟踪来形象化进程的概念: 在进程运行轨迹跟踪的基础上进行相应的数据统计,从而能对进程调度算法进行 ...
- 北航linux内核编译及烧录实验报告,北航操作系统实验Lab1笔记
Loading... # 北航操作系统实验Lab1 ## Exercise 1.1 - **修改交叉编译路径为 `/OSLAB/compiler/usr/bin/mips_4KC-`** ![ex1_ ...
- java 动态分区 链表_大二作业——操作系统实验——C语言用双向链表,模拟实现动态分区式存储管理...
实验:动态分区式存储管理 实验内容: 编写程序模拟完成动态分区存储管理方式的内存分配和回收.实验具体包括:首先确定内存空闲分配表:然后采用最佳适应算法完成内存空间的分配和回收:最后编写主函数对所做工作 ...
- 操作系统 实验报告 linux 内核,linux操作系统内核实验报告.doc
linux操作系统内核实验报告.doc linux操作系统内核实验报告 篇一:linux操作系统实验报告 LINUX操作系统实验报告 姓 名 班级学号 指导教师 2011 年 05月 16 日 实验一 ...
最新文章
- [k8s] 第六章 Pod控制器详解(Controller-manager)
- 硬件三人行-开关电源学习笔记-1
- 【干货】移动互联网时代的零售店面转型之道
- 解决接收参数乱码,tomcat的URIEncoding=UTF-8
- 多个线程作用于同一个runnable对象
- Android的权限
- Android学习系列(41)--Android Studio简单使用
- MATLAB符号运算部分知识总结
- Excel表格转换为Word表格,并且保留Excel表格中公式不发生变化
- C4D渲染保存多通道psd格式,图层都是线性减淡模式,oc多通道图层都是线性简单模式
- “微笑妹妹”9岁撑起一个家
- Servlet常见错误 404错误 405错误 500错误等。解决方法
- 学习太极创客 — MQTT 第二章(一)QoS 服务质量等级
- 上线网站详细介绍(服务器购买-域名申请-SSL证书申请)
- QtQuick串口编程Demo
- 区块链游戏为何如此火?大概是因为投机者和“韭菜”太多
- html游戏禁止微信浏览器下拉,JavaScript中防止微信浏览器被整体拖动的方法
- HOOK Windows API
- 安装autodesk系列无法安装解决办法
- Android使用Intent发送短信SMS
热门文章
- Java—集合框架图
- 从网站抓取数据的3种最佳方法
- [读论文]三维激光扫描点云数据处理研究进展、挑战与趋势(2017)
- webdriver中PDF控件无法显示的问题(IE兼容性)
- C语言实例第8期:模拟银行账户登陆
- Linux 常用 shell 命令
- lopatkin俄大神精简中文系统Windows 10 Enterprise 18362.145 19H1 Release x86-x64 ZH-CN BOX
- java开发业务流程图,什么是业务流程图?业务流程图如何绘制?
- Axure rp8元件库载入失败怎么解决
- mysql sqlyog 1045_sqlyog错误代码1045