操作系统实验报告.docx
- 文档编号:22839719
- 上传时间:2023-04-28
- 格式:DOCX
- 页数:38
- 大小:207.15KB
操作系统实验报告.docx
《操作系统实验报告.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告.docx(38页珍藏版)》请在冰豆网上搜索。
操作系统实验报告
操作系统原理
实验报告
学生姓名
学号
专业班级
指导教师
学院信息科学与工程学院
实验时间2014年月5日
实验一处理机调度
一、实验目的
多道系统中,当就绪进程数大于处理机数时,须按照某种策略决定哪些进程优先占用处理机。
本实验模拟实现处理机调度,以加深了解处理机调度的工作。
二、实验内容
设计实现处理机调度算法。
三、实验要求
1、设计一个有几个进程并发执行的进程调度程序,每个进程由一个进程控制块(PCB)表示,进程控制块通常应包括下述信息:
进程名,进程PID,进程优先数,进程状态、PCB指针等,且可按照调度算法的不同而增删。
2、调度算法包括:
优先权调度算法和时间片轮转调度算法。
3、程序应能显示或打印各进程状态和参数的变化情况,便于观察。
4、可随时增加新进程。
四、实验分析与设计
时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法。
每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。
如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。
如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。
调度程序所要做的就是维护一张就绪进程列表,当进程用完它的时间片后,它被移到队列的末尾。
优先权调度算法就是紧迫型作业进入系统后能得到优先处理的意思。
当该算法用于作业调度时,系统从后备作业队列中选择若干个优先级最高的,且系统能满足资源要求的作业装入内存运行。
或者当该算法用于进程调度时,将把处理机分配给就绪进程队列中优先级最高的进程。
五、实验运行结果与相关代码
代码:
时间片轮转调度算法
#include
#include
usingnamespacestd;
typedefstructPNode{
structPNode*next;
charname[10];
intAll_Time;
intRuned_Time;
charstate;
}*Proc;
intProcNum;
voidInitPCB(Proc&H)
{
cout<<"请输入进程数量:
";
cin>>ProcNum;
intNum=ProcNum;
H=(Proc)malloc(sizeof(PNode));
H->next=NULL;
Procp=H;
cout<<"请按格式输入进程信息:
\n";
while(Num--)
{
p=p->next=(Proc)malloc(sizeof(PNode));
cout<<"进程名所需花费总时间已经运行时间"< cin>>p->name>>p->All_Time>>p->Runed_Time; p->state='R'; p->next=NULL; } p->next=H->next; } voidDispInfo(ProcH) { Procp=H->next; do{ if(p->state! ='E') { cout<<"进程名: "< "< "< "< p=p->next; } elsep=p->next; } while(p! =H->next); } voidSJP_Simulator(Proc&H){ cout< \n"; intflag=ProcNum; intround=0; Procp=H->next; while(p->All_Time>p->Runed_Time) { round++; cout< p->Runed_Time++; DispInfo(H); if(p->All_Time==p->Runed_Time) { p->state='E'; flag--; cout< \n"; } p=p->next; while(flag&&p->All_Time==p->Runed_Time) p=p->next; } cout< \n"; } voidmain() { ProcH; InitPCB(H); DispInfo(H); SJP_Simulator(H); system("pause"); } 运行截图 (中间过程太多,只截取几张。 ) 优先权调度算法 #include"stdio.h" #include"string.h" #include usingnamespacestd; #definenum4//假定系统中进程个数为5 structPCB{ charID; intruntime; intpri; charstate; }; structPCBpcblist[num]; voidinit() { inti; for(i=0;i { printf("进程%d: 进程名优先权运行时间\n",i+1); scanf("%s%d%d",&pcblist[i].ID,&pcblist[i].pri,&pcblist[i].runtime); pcblist[i].state='R'; getchar(); } } intmax_pri_process() { intmax=-100; inti; intkey; for(i=0;i { if(pcblist[i].state=='r') return-1; else if(max { max=pcblist[i].pri; key=i; } } if(pcblist[key].state=='F') return-1; else returnkey; } voidshow() { inti; printf("\n进程名优先权运行时间\n"); printf("-------------------------------------------------\n"); for(i=0;i { printf("%s%6d%8d\n",&pcblist[i].ID,pcblist[i].pri,pcblist[i].runtime); } printf("开始! \n"); } voidrun() { inti,j; intt=0; for(j=0;j { t+=pcblist[j].runtime;} printf("\n初态为: \n"); show(); getchar(); for(j=0;j { while(max_pri_process()! =-1) { pcblist[max_pri_process()].state='r'; } for(i=0;i { if(pcblist[i].state=='r') { pcblist[i].pri-=1; pcblist[i].runtime--; { if(pcblist[i].runtime==0) pcblist[i].state='F'; else pcblist[i].state='R'; } show(); getchar(); } } } } voidmain() { cout<<"此程序默认运行4个进程。 "< init(); run(); } 运行截图 6、收获与体会 此次实验使得我对两个处理机调度的算法更加熟悉了,关于时间片轮转算法,可以发现它还是有些瓶颈的,比如整个系统中只有一个就绪队列供多个处理器共享。 低效性,线程在其生命周期内多次更换处理器使得高速缓存的使用率很低,线程切换频繁,但某种程度上来说,这种时间片轮算法结合优先权算法是非常合理的算法,足以面对许多状况了。 实验二死锁避免实验 一、实验目的 多个进程动态地共享系统的资源时可能会产生死锁现象。 银行家算法是通过对资源的分配进行动态地检查来达到避免死锁的目的。 本实验通过模拟银行家算 法的应用,使读者了解银行家算法的执行过程。 从而进一步理解死锁产生的条件 和避免死锁问题产生的方法。 二、实验内容 死锁避免实验 三、实验要求 1、设资源种类为N,每类资源的初始可用数目为1-M,N和M输入或预定义 2、初始时资源全部可用。 运行时,随机生成或手工输入新的进程资源请求。 3、编写程序模拟银行家算法 4、显示每次资源请求处理后的处理结果和资源状态。 4、实验分析与设计 操作系统中的死锁被定义为系统中两个或者多个进程无限期地等待永远不会发生的条件,系统处于停滞状态,这就是死锁。 产生死锁的原因要是: 1.系统资源不足 2.进程运行推进的顺序不合适 3.资源分配不当 如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。 其次,进程运行推进顺序与速度不同,也可能产生死锁。 产生死锁的四个必要条件: 1) 互斥条件: 一个资源每次只能被一个进程使用。 (2) 请求与保持条件: 一个进程因请求资源而阻塞时,对已获得的资源保持不放。 (3) 不剥夺条件: 进程已获得的资源,在末使用完之前,不能强行剥夺。 (4) 环路等待条件: 若干进程之间形成一种头尾相接的循环等待资源关系。 这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。 避免死锁是在资源的动态分配过程中,用某种方法去防止系统进入不安全状态,从而避免死锁,而不需事先采取各种限制措施去破坏产生死锁的四个必要条件。 这种方法施加的限制条件较弱,但在实现上有一定的难度。 5、试验运行结果与相关代码 代码: #include #include #include #include #defineM5/*进程数*/ #defineN3/*资源数*/ #defineFALSE0 #defineTRUE1 /*M个进程对N类资源最大资源需求量*/ intMAX[M][N]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}}; /*系统可用资源数*/ intAVAILABLE[N]={10,5,7}; /*M个进程已分配到的N类数量*/ intALLOCATION[M][N]={{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}}; /*M个进程已经得到N类资源的资源量*/ intNEED[M][N]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}}; /*M个进程还需要N类资源的资源量*/ intRequest[N]={0,0,0}; voidmain() { inti=0,j=0; charflag; voidshowdata(); voidchangdata(int); voidrstordata(int); intchkerr(int); showdata(); enter: { printf("请输入需申请资源的进程号(从0到"); printf("%d",M-1); printf("): "); scanf("%d",&i); } if(i<0||i>=M){ printf("输入的进程号不存在,重新输入! \n"); gotoenter; } err: { printf("请输入进程"); printf("%d",i); printf("申请的资源数\n"); printf("类别: ABC\n"); printf(""); for(j=0;j { scanf("%d",&Request[j]); if(Request[j]>NEED[i][j]) { printf("%d",i); printf("号进程"); printf("申请的资源数>进程"); printf("%d",i); printf("还需要"); printf("%d",j); printf("类资源的资源量! 申请不合理,出错! 请重新选择! \n"); gotoerr; } else { if(Request[j]>AVAILABLE[j]) { printf("进程"); printf("%d",i); printf("申请的资源数大于系统可用"); printf("%d",j); printf("类资源的资源量! 申请不合理,出错! 请重新选择! \n"); gotoerr; } } } } changdata(i); if(chkerr(i)) { rstordata(i); showdata(); } else showdata(); printf("\n"); printf("按'y'或'Y'键继续,否则退出\n"); flag=getch(); if(flag=='y'||flag=='Y') { gotoenter; } else { exit(0); } } /*显示数组*/ voidshowdata() { inti,j; printf("系统可用资源向量: \n"); printf("***Available***\n"); printf("资源类别: ABC\n"); printf("资源数目: "); for(j=0;j { printf("%d",AVAILABLE[j]); } printf("\n"); printf("\n"); printf("各进程还需要的资源量: \n"); printf("******Need******\n"); printf("资源类别: ABC\n"); for(i=0;i { printf(""); printf("%d",i); printf("号进程: "); for(j=0;j { printf("%d",NEED[i][j]); } printf("\n"); } printf("\n"); printf("各进程已经得到的资源量: \n"); printf("***Allocation***\n"); printf("资源类别: ABC\n"); for(i=0;i { printf(""); printf("%d",i); printf("号进程: "); /*printf(": \n");*/ for(j=0;j { printf("%d",ALLOCATION[i][j]); } printf("\n"); } printf("\n"); } /*系统对进程请求响应,资源向量改变*/ voidchangdata(intk) { intj; for(j=0;j { AVAILABLE[j]=AVAILABLE[j]-Request[j]; ALLOCATION[k][j]=ALLOCATION[k][j]+Request[j]; NEED[k][j]=NEED[k][j]-Request[j]; } } /*资源向量改变*/ voidrstordata(intk) { intj; for(j=0;j { AVAILABLE[j]=AVAILABLE[j]+Request[j]; ALLOCATION[k][j]=ALLOCATION[k][j]-Request[j]; NEED[k][j]=NEED[k][j]+Request[j]; } } /*安全性检查函数*/ intchkerr(ints) { intWORK,FINISH[M],temp[M]; inti,j,k=0; for(i=0;i for(j=0;j { WORK=AVAILABLE[j]; i=s; while(i { if(FINISH[i]==FALSE&&NEED[i][j]<=WORK) { WORK=WORK+ALLOCATION[i][j]; FINISH[i]=TRUE; temp[k]=i; k++; i=0; } else { i++; } } for(i=0;i if(FINISH[i]==FALSE) { printf("\n"); printf("系统不安全! 本次资源申请不成功! \n"); printf("\n"); return1; } } printf("\n"); printf("经安全性检查,系统安全,本次分配成功。 \n"); printf("\n"); printf("本次安全序列: \n"); printf("进程依次为"); for(i=0;i { printf("%d",temp[i]); printf("->"); } printf("\n"); return0; } 截图 6、收获与体会 在避免死锁的方法中,所施加的限制条件较弱,有可能获得令人满意的系统性能。 在该方法中把系统的状态分为安全状态和不安全状态,只要能使系统始终都处于安全状态,便可以避免发生死锁。 我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。 这种方式很形象,而且例子非常经典,可以说,算法的世界里是可以将许多东西具象变成一些例子,然后大家的思想一起集聚,比拼,实在非常有趣。 实验三虚拟页式管理实验 一、实验目的 加深理解虚拟页式管理的基本思想以及实现过程、相关数据结构 二、实验内容 设计一个模拟虚拟页式管理的程序。 三、实验要求 1.设计并实现一个虚存管理程序,模拟一个单道程序的虚拟页式存储管理。 2.程序中使用随机数函数rand()产生的随机数作为要访问的虚地址,为简单起见,该随机数的最低位兼做修改标志。 分配的主存块号也使用rand()产生。 3.实现函数response()响应访存请求,完成虚地址到实地址的定位,同时判断并处理缺页中断。 4.实现OPT,FIFO,LRU和Clock页面置换算法。 4、实验分析与设计 在地址映射过程中,若在页面中发现所要访问的页面不在内存中,则产生缺页中断。 当发生缺页中断时,如果操作系统内存中没有空闲页面,则操作系统必须在内存选择一个页面将其移出内存,以便为即将调入的页面让出空间。 而用来选择淘汰哪一页的规则叫做页面置换算法。 选择置换算法,先输入所有页面号,为系统分配物理块,依次进行置换: OPT基本思想: 是用一维数组page[pSIZE]存储页面号序列,memery[mSIZE]是存储装入物理块中的页面。 数组next[mSIZE]记录物理块中对应页面的最后访问时间。 每当发生缺页时,就从物理块中找出最后访问时间最大的页面,调出该页,换入所缺的页面。 【特别声明】 若物理块中的页面都不再使用,则每次都置换物理块中第一个位置的页面。 FIFO基本思想: 是用队列存储内存中的页面,队列的特点是先进先出,与该算法是一致的,所以每当发生缺页时,就从队头删除一页,而从队尾加入缺页。 或者借助辅助数组time[mSIZE]记录物理块中对应页面的进入时间,每次需要置换时换出进入时间最小的页面。 LRU基本思想: 是用一维数组page[pSIZE]存储页面号序列,memery[mSIZE]是存储装入物理块中的页面。 数组flag[10]标记页面的访问时间。 每当使用页面时,刷新访问时间。 发生缺页时,就从物理块中页面标记最小的一页,调出该页,换入所缺的页面。 5、实验运行结果与相关代码 代码: #include #include #include voidrand(intn,intp[])//该函数是产生n个1~10的随机数放到p[]数组里面 { intSTART=1; intEND=10; intv; inti; inta; srand(time(NULL)); for(i=0;i { v=rand()%(END-START+1)+START; p[i]=v; cout< } } structPro { intnum,time; //num存放具体的内容,time在不同算法里面有不同的意义 }; //它们是物理块和页面的数据结构 intInput(intm,intN,Pro*p,Pro*page) //完成p[]数组和page[]的初始化工作 {//p[]数组是存放页面的空间,m是页面的长度 //page[]是可以使用的物理块,N是物理块的大小 cout< int*p2=newint[m]; rand(m,p2); for(inti=0;i { p[i].num=p2[i]; p[i].time=0; } for(i=0;i //初试化页面基本情况 { page[i].num=0; page[i].time=N+2-i; } returnm; } intSearch(inte,Pro*page,intN) //算法里面都要用到
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)