koorio.com
海量文库 文档专家
当前位置:首页 >> 计算机软件及应用 >>

OS实验报告格式

2012-2013 学年第一学期

计算机操作系统实验报告

实验一 Windows多线程

【开发语言及实现平台或实验环境】
C++/C# Microsoft Visual Studio 6.0/ Microsoft Visual Studio .NET

【实验目的】
(1) 进一步理解操作系统的并发性; (2) 了解 Windows 线程创建方法,并通过查阅资料理解各参数的含义; (3) 了解多线程程序设计方法,并进行简单应用。

【实验要求】
(1) 逐程序进行简要分析、运行各程序并仔细阅读注释; (2) 查阅 MSDN 或其他资料,掌握相关系统调用使用方法和参数含义; (3) 完成实验报告。

【实验结果与分析】

1

Sleep是阻塞线程函数。它会在当前语句阻塞一段时间,参数是以1/1000秒为单位的,线程1 和主线程并发执行,Sleep(10) 使当前线程放弃目前的时间片,并且在 10ms 内不会被

再次调度。会使主进程和分进程同时被调度,进程也有父子关系。父进程退出后子进程也会 退出,而加入Sleep后主进程先停止10后子进程就有时间进行了。

加入循环,使得俩个进程交替执行,出现俩个1,俩个6是因为不可再现性,即俩个进程同时 迈出同一部步,俩个进程中存在共享变量。因为加入while所以不需要sleep,父子进程也能 同时进行。
2

加入sleep(1000)后父进程有足够的时间运行子进程

3

加入俩个sleep(1)后,有可能到thread1 is sell tickets:时间片就停了,tickets没--,还可以运行 thread2 is sell tickets:"<<tickets—也就是说tickets变为0,返回再运行thread1 is sell tickets时就 卖0号票了 【实验思考及总结】 ……………………… 加入循环,使得俩个进程交替执行 Sleep 是阻塞线程函数。它会在当前语句阻塞一段时间,参数是以 1/1000 秒为单位的 线程也有父子关系。父进程退出后子进程也会退出 不可再现性,即俩个进程同时迈出同一部步,俩个进程中存在共享变量

4

实验二 Windows线程同步机制

【开发语言及实现平台或实验环境】
C++/C# Microsoft Visual Studio 6.0/ Microsoft Visual Studio .NET

【实验目的】
(1) 了解 Windows 线程同步机制; (2) 了解互斥体,并通过查阅资料理解互斥体对象的使用方法; (3) 了解事件,并通过查阅资料理解事件对象的使用方法; (4) 了解关键区,并通过查阅资料理解关键区对象的使用方法; (5) 了解信号量,并通过查阅资料理解信号量对象的使用方法; (6) 利用Windows线程同步机制,模拟生产者消费者问题。

【实验要求】
(1) 逐程序进行简要分析、运行各程序并仔细阅读注释; (2) 查阅 MSDN 或其他资料,掌握相关系统调用使用方法和参数含义; (3) 完成实验报告。

【实验结果与分析】

5

2-1到2-3加入俩个sleep(1)后,有可能到thread1 is sell tickets:时间片就停了,tickets没--,还 可以运行thread2 is sell tickets:"<<tickets—也就是说tickets变为0,返回再运行thread1 is sell tickets时就卖0号票了

6

7

【实验思考及总结】 Sleep(10) 使当前线程放弃目前的时间片,并且在

10ms

内不会被再次调度

进程也有父子关系。父进程退出后子进程也会退出,线程之间的同步使用一些核心对象: 如 thread, process, evnet, mutex, semaphore. 在线程之间使用等待函数如 WaitForSingleObjects, WaitForMultipleObjects. 等待函数使用核心对象的 handle 作为参 数,如果 handle 被激发,则执行下一步。 handle 被激发的条件: (handle 是一段内存指 针,为了掩藏内部实现而作的一个类型转化指针)激发:---我的理解是资源未被战胜。 未激发: ---资源正在被占用。 eg: 1)thread, process 被终止, 则激发。 2) event: 要 通过它的 API 来手动激发,是最灵活的激发方式,可被所有线程使用。 3)mutex: 没被任何 线程所拥有,则激发。 1)临界区: CRITICAL_SECTION 适用范围: 单一进程的各线程之间用来排它性占有特性: 局部性对象; 快速而有效. 无法监测是否被线程放弃函数: EnterCriticalSection LeaveCriticalSection 2)Mutex: 适用范围: 不同线程之间用来排它性占有特性: 核心对象, 可以使用 wait 进行等 待,只能被拥有线程所释放函数:CreateMutex ReleaseMutex 3)semaphore: 信号量 适用范围: 用来限制资源占用特性: 核心对象,没有拥有者,任何线程 都可释放函数:CreateSemaphore OpenSemaphore ReleaseSemaphore

8

4)Event: 适用范围: 同来控制对象信号的接收,常与信号系统结合起来特性: 核心对象函数: CreateEvent OpenEvent PulseEvent SetEvent ResetEvent 作,如写文件中对文件中字节范围的锁定_locking NOTE: 线程同步中很重要的可归纳为锁系统 lock 和信号系统 signal lock 包 括:CRITICAL_SECTION, Mutex, wait function: WaitForMultipleObjects WaitForSingleObject Sleep 6)completion port 适用范围: 网络异步接收,包括文件读写 5)Interlocked 简单的原子操

特性:由 OS 来控制读写, 是 windows 平台最有效的同步机制,相当于 linux 的 AIO 或者非阻 塞 socket+epoll 函数: CreateIoCompletionPort GetQueuedCompletionStatus 示例 1: event //事件机制: 设置一个全局 event 对象,这个只能等待最多 64 个对象,而且要用 WaitForMultipleObjects 来监视线 程 handle 数组. 不如完全端口 completion port HANDLE ghWriteEvent; HANDLE ghThreads[THREADCOUNT]; //(1)创建个手动事件,一开始不接受任何信号 no signel //ResetEvent: 用来信号重置,同 CreateEvent or OpenEvent CreateEvent( manual-reset event nonsignaled 件响应信号 signal, NULL, FALSE, ghWriteEvent = TRUE, //

// default security attributes // initial state is

TEXT("WriteEvent") // object name if (! SetEvent(ghWriteEvent) ) return; {

); //(2)产生一堆线程,设置事 printf("SetEvent failed

(%d)/n", GetLastError());

} //(3)设置线程等待事件,所有线程都接到这个事 dwWaitResult =

件,,这里对线程进行了同步,只有所有线程都执行了,才执行下一步 WaitForMultipleObjects( array signaled ghThreads, THREADCOUNT,

// number of handles in TRUE, // wait until all are

// array of thread handles

INFINITE); { //(3.1)其中每个线程函数都在等待事件对象,这里也对线程进行

了同步,只有得到 signal 的线程才执行下一步 dwWaitResult = WaitForSingleObject( indefinite wait } //(4)关闭了这个全局事件 == CloseHandle(ghWriteEvent) CloseEvents(); 示例 2: completion port (1) 创建完成端口, 与一个监听 socket 发生关联 CreateIoCompletionPort (2) 产生一堆线程,让线程在完全端口循环等待. CreateThread--(WorkerThread)-GetQueuedCompletionStatus (3) 接收监听 socket 的读写请求 accept,将 accept socket 与完全端口关联
9

ghWriteEvent, // event handle

INFINITE);

//

10

实验三 Windows线程通信

【开发语言及实现平台或实验环境】
C++/C# Microsoft Visual Studio 6.0/ Microsoft Visual Studio .NET

【实验目的】
(1) 了解 Window 线程通信方法; (2) 了解匿名管道,并通过查阅资料理解匿名管道的使用方法; (3) 了解命名管道,并通过查阅资料理解命名管道的使用方法;

【实验要求】
(1) 逐程序进行简要分析、运行各程序并仔细阅读注释; (2) 查阅 MSDN 或其他资料,掌握相关系统调用使用方法和参数含义; (3) 完成实验报告。

【实验结果与分析】

11

12

13

【实验思考及总结】 学会了在 vc6.0 中 open 已经编译好的程序,选择所有文件,线程之间通信的两个基本问题 是互斥和同步。 线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消 息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒。 线程互斥是指对于共享的操作系统资源(指的是广义的"资源",而不是 Windows 的.res 文件,譬如全局变量就是一种共享资源) ,在各线程访问时的排它性。当有若干个线程都要 使用某一共享资源时, 任何时刻最多只允许一个线程去使用, 其它要使用该资源的线程必须 等待,直到占用资源者释放该资源。 线程互斥是一种特殊的线程同步。 实际上,互斥和同步对应着线程间通信发生的两种情况: (1)当有多个线程访问共享资源而不使资源被破坏时; (2)当一个线程需要将某个任务已经完成的情况通知另外一个或多个线程时。 在 WIN32 中,同步机制主要有以下几种: (1)事件(Event); (2)信号量(semaphore); (3)互斥量(mutex); (4)临界区(Critical section)。 全局变量 因为进程中的所有线程均可以访问所有的全局变量,因而全局变量成为 Win32 多线程 通信的最简单方式。例如:

14

实验四 银行家算法模拟
【开发语言及实现平台或实验环境】 C++/C# Microsoft Visual Studio 6.0/ Microsoft Visual Studio .NET 2003 【实验目的】 (1)进一步理解利用银行家算法避免死锁的问题; (2)在了解和掌握银行家算法。 (3)理解和掌握安全序列、安全性算法 【实验内容】 (1)编写安全性算法; (2)编写银行家算法,并编制银行家算法通用程序,将调试结果显示在计算机屏幕上,再 检测和笔算的一致性。

【源代码】
#include<iostream> using namespace std; #include<string.h> #include<stdio.h> #define False 0 #define True 1 int Max[100][100]={0};//各进程所需各类资源的最大需求 int Avaliable[100]={0};//系统可用资源 char name[100]={0};//资源的名称 int Allocation[100][100]={0};//系统已分配资源 int Need[100][100]={0};//还需要资源 int Request[100]={0};//请求资源向量 int temp[100]={0};//存放安全序列 int Work[100]={0};//存放系统可提供资源 int M=100;//作业的最大数为 100 int N=100;//资源的最大数为 100 void showdata()//显示资源矩阵 { int i,j; cout<<"系统目前可用的资源[Avaliable]:"<<endl; for(i=0;i<N;i++)cout<<name[i]<<" "; cout<<endl; for (j=0;j<N;j++)cout<<Avaliable[j]<<" ";//输出分配资源 cout<<endl; cout<<" Max Allocation Need"<<endl; cout<<"进程名 ";
15

for(j=0;j<3;j++){ for(i=0;i<N;i++)cout<<name[i]<<" "; cout<<" "; } cout<<endl; for(i=0;i<M;i++){ cout<<" "<<i<<" "; for(j=0;j<N;j++)cout<<Max[i][j]<<" "; cout<<" "; for(j=0;j<N;j++)cout<<Allocation[i][j]<<" "; cout<<" "; for(j=0;j<N;j++)cout<<Need[i][j]<<" "; cout<<endl; } } int changdata(int i)//进行资源分配 { int j; for (j=0;j<M;j++) { Avaliable[j]=Avaliable[j]-Request[j]; Allocation[i][j]=Allocation[i][j]+Request[j]; Need[i][j]=Need[i][j]-Request[j]; } return 1; } int safe()//安全性算法 { int i,k=0,m,apply,Finish[100]={0}; int j; int flag=0; for(i=0;i<N;i++) { Work[i]=Avaliable[i]; } for(i=0;i<M;i++){ apply=0; for(j=0;j<N;j++){ if (Finish[i]==False&&Need[i][j]<=Work[j]){ apply++; if(apply==N){ for(m=0;m<N;m++)Work[m]=Work[m]+Allocation[i][m];//变分配数 Finish[i]=True; temp[k]=i;i=-1; k++;flag++;

16

} } } } for(i=0;i<M;i++){ if(Finish[i]==False){ cout<<"系统不安全"<<endl;//不成功系统不安全 return -1; } } cout<<"系统是安全的!"<<endl;//如果安全,输出成功 cout<<"分配的序列:"; for(i=0;i<M;i++){//输出运行进程数组 cout<<temp[i]; if(i<M-1) cout<<"->"; } cout<<endl; return 0; } void share()//利用银行家算法对申请资源对进行判定 { char ch; int i=0,j=0; ch='y'; cout<<"请输入要求分配的资源进程号(0-"<<M-1<<"):"; cin>>i;//输入须申请的资源号 cout<<"请输入进程 "<<i<<" 申请的资源:"<<endl; for(j=0;j<N;j++){ cout<<name[j]<<":"; cin>>Request[j];//输入需要申请的资源 } for (j=0;j<N;j++){ if(Request[j]>Need[i][j])//判断申请是否大于需求,若大于则出错 { cout<<"进程 "<<i<<"申请的资源大于它需要的资源"; cout<<" 分配不合理,不予分配!"<<endl; ch='n'; break; } else { if(Request[j]>Avaliable[j])//判断申请是否大于当前资源,若大于则 { //出错 cout<<"进程"<<i<<"申请的资源大于系统现在可利用的资源";

17

cout<<" 分配出错,不予分配!"<<endl; ch='n'; break; } } } if(ch=='y') { changdata(i);//根据进程需求量变换资源 showdata();//根据进程需求量显示变换后的资源 safe();//根据进程需求量进行银行家算法判断 } } void addresources(){//添加资源 int n,flag; cout<<"请输入需要添加资源种类的数量:"; cin>>n; flag=N; N=N+n; for(int i=0;i<n;i++){ cout<<"名称:"; cin>>name[flag]; cout<<"数量:"; cin>>Avaliable[flag++]; } showdata(); safe(); } void delresources(){//删除资源 char ming; int i,flag=1; cout<<"请输入需要删除的资源名称:"; do{ cin>>ming; for(i=0;i<N;i++) if(ming==name[i]){ flag=0; break; } if(i==N) cout<<"该资源名称不存在,请重新输入:"; } while(flag); for(int j=i;j<N-1;j++){ name[j]=name[j+1];

18

Avaliable[j]=Avaliable[j+1]; } N=N-1; showdata(); safe(); } void changeresources(){//修改资源函数 cout<<"系统目前可用的资源[Avaliable]:"<<endl; for(int i=0;i<N;i++) cout<<name[i]<<":"<<Avaliable[i]<<endl; cout<<"输入系统可用资源[Avaliable]:"<<endl; cin>>Avaliable[0]>>Avaliable[1]>>Avaliable[2]; cout<<"经修改后的系统可用资源为"<<endl; for (int k=0;k<N;k++) cout<<name[k]<<":"<<Avaliable[k]<<endl; showdata(); safe(); } void addprocess(){//添加作业 int flag=M; M=M+1; cout<<"请输入该作业的最打需求量[Max]"<<endl; for(int i=0;i<N;i++){ cout<<name[i]<<":"; cin>>Max[flag][i]; Need[flag][i]=Max[flag][i]-Allocation[flag][i]; } showdata(); safe(); } int main()//主函数 { int i,j,number,choice,m,n,flag; char ming; cout<<"*****************资源管理系统的设计与实现*****************"<<endl; cout<<"请首先输入系统可供资源种类的数量:"; cin>>n; N=n; for(i=0;i<n;i++){ cout<<"资源"<<i+1<<"的名称:"; cin>>ming; name[i]=ming; cout<<"资源的数量:"; cin>>number;

19

Avaliable[i]=number; } cout<<endl; cout<<"请输入作业的数量:"; cin>>m; M=m; cout<<"请输入各进程的最大需求量("<<m<<"*"<<n<<"矩阵)[Max]:"<<endl; for(i=0;i<m;i++) for(j=0;j<n;j++) cin>>Max[i][j]; do{ flag=0; cout<<"请输入各进程已经申请的资源量("<<m<<"*"<<n<<"矩阵)[Allocation]:"<<endl; for(i=0;i<m;i++) for(j=0;j<n;j++){ cin>>Allocation[i][j]; if(Allocation[i][j]>Max[i][j]) flag=1; Need[i][j]=Max[i][j]-Allocation[i][j]; } if(flag) cout<<"申请的资源大于最大需求量,请重新输入!\n"; } while(flag); showdata();//显示各种资源 safe();//用银行家算法判定系统是否安全 while(true){ cout<<"**************银行家算法演示***************"<<endl; cout<<" 1:增加资源 "<<endl; cout<<" 2:删除资源 "<<endl; cout<<" 3:修改资源 "<<endl; cout<<" 4:分配资源 "<<endl; cout<<" 5:增加作业 "<<endl; cout<<" 0:离开 "<<endl; cout<<"*******************************************"<<endl; cout<<"请选择功能号:"; cin>>choice; switch(choice){ case 1: addresources();break; case 2: delresources();break; case 3: changeresources();break; case 4: share();break; case 5: addprocess();break; case 0: choice=0;break;

20

default: cout<<"请正确选择功能号(0-5)!"<<endl;break; } } return 1; }

【实验结果与分析】

21

【实验思考及总结】 银行家算法的安全算法不唯一, 我们可以把操作系统看作是银行家, 操作系统管理的资源相 当于银行家管理的资金, 进程向操作系统请求分配资源相当于用户向银行家贷款。 操作系统

22

按照银行家制定的规则为进程分配资源, 当进程首次申请资源时, 要测试该进程对资源的最 大需求量, 如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源, 否则 就推迟分配。 当进程在执行中继续申请资源时, 先测试该进程已占用的资源数与本次申请的 资源数之和是否超过了该进程对资源的最大需求量。 若超过则拒绝分配资源, 若没有超过则 再测试系统现存的资源能否满足该进程尚需的最大资源量, 若能满足则按当前的申请量分配 资源,否则也要推迟分配。

23

实验五

页面置换算法模拟

【开发语言及实现平台或实验环境】 C++/C# Microsoft Visual Studio 6.0/ Microsoft Visual Studio .NET 2003 【实验目的】 (1)进一步理解利用页面调度算法实现虚拟内存的问题; (2)通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特 点。 (3)掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程, 并比较它们的效率。 (4)了解页面大小和内存实际容量对命中率的影响。 【实验内容】 (1)在了解和掌握页面调度算法的基础上,编制先进先出的算法(FIFO)、最近最少使用 算法(LRU)、最佳淘汰算法(OPT)等各种页面置换算法。将调试结果显示在计算机屏幕上, 再检测和笔算的一致性。 (2)理解和掌握命中率的问题 (3)会使用某种编程语言。

【源代码】
#include <iostream> #include <deque> #include <ctime> using namespace std; typedef struct { int id; //页面 ID int stayTime; //内存中驻留时间 int unUseTime; //已经多久未被使用 }CPage; deque<int> RunQueue; deque<CPage> interPage; //内存中的四个页面 deque<CPage> exterPage; //外存中的 N 个页面 int presentSeat; //目前运行到了队列的第几个? int lackNum[3] ={0}; int getRandNum(int range) //返回[0,range)范围内的整数 { return static_cast<int>(rand()%range); } int findPageIdByCmdId(int cmdId) //通过强制转换成整数的形式判断指令属于哪个页面
24

{ return static_cast<int>(cmdId/10); } void InitDevice() //初始化运行队列 按照 25% 50% 25%的标准生成 { srand(static_cast<int>(time(NULL))); int t_cmdNum = getRandNum(320); //随机选择第一条指令 RunQueue.push_back(t_cmdNum); //将其插入队列 if(t_cmdNum < 319) RunQueue.push_back(t_cmdNum+1); //顺序执行下一条指令 while(RunQueue.size() <= 320) { t_cmdNum = getRandNum(t_cmdNum); //跳转到 m1 属于[0,m-1] RunQueue.push_back(t_cmdNum); //将 m1 插入队列 if(t_cmdNum < 319) RunQueue.push_back(t_cmdNum+1); //将 m1+1 插入队列 int temp = 320 - (t_cmdNum + 2); t_cmdNum = t_cmdNum+2+getRandNum(temp);//跳转到 m2 属于[m+2,319] RunQueue.push_back(t_cmdNum); //插入队列 if(t_cmdNum < 319) RunQueue.push_back(t_cmdNum+1); //将 m2+1 插入队列 } while(RunQueue.size() > 320) RunQueue.pop_back(); } void InitMemoryQueue() //初始化运行标志、内存外存页面队列 { presentSeat = 0; exterPage.clear(); interPage.clear(); for(int i=0;i<32;i++) { CPage temp; temp.id = i; temp.stayTime = 0; temp.unUseTime = 0; exterPage.push_back(temp); } } int searchStatusOfPage(int t_PageId,bool sign) //分别在内外存中查找页面 存在返回位置 不 存在返回-1 { if(sign)

25

for(unsigned i=0;i<interPage.size();i++) { if(t_PageId == interPage[i].id) return i; } //这里的括号不能删除,否则 if else 的匹配会出问题 else for(unsigned j=0;j<exterPage.size();j++) if(t_PageId == exterPage[j].id) return j; return -1; } int searchNextStatusOfInterPage(int start, int id) //OPT 算法中查找内存页面中的页面下次需要 用到它的时候的队列下标 { //找到就返回下标 没找到就返回-1 for(int i=start;i < 320;i++) if(static_cast<int>(RunQueue[i]/10) == id) return i; return -1; } int findLongestStayTimePage() //FIFO 算法中查找在内存中呆了最久的页面 { int max = 0; for(unsigned i=1;i<interPage.size();i++) if(interPage[i].stayTime>interPage[max].stayTime) max = i; return max; } int findLongestUnUseTimePage() //LRU 算法中查找最久未使用的页面 { int max = 0; for(unsigned j=0;j<interPage.size();j++) if(interPage[j].unUseTime>interPage[max].unUseTime) max = j; return max; } int findNeedLongestTimePage() //OPT 算法中查找最长时间不会用到的页面 { deque<int> temp; for(unsigned i=0;i < interPage.size();i++) { int it = searchNextStatusOfInterPage(presentSeat,interPage[i].id); if(it == -1) return i; temp.push_back(it);

26

} int max = -1,status = 0; for(unsigned j=1;j < temp.size();j++) { if(max < temp[j]) { max = temp[j]; status = j; } } return status; //返回需要最长时间才执行的页面在内存中的位置 } void directFlod(int t_PageId) //当内存空间还有剩余时直接调入 { int status = searchStatusOfPage(t_PageId,false); if(status == -1) return; interPage.push_back(exterPage[status]); //先插入节点到内存,再从外存中将其删除 exterPage.erase(exterPage.begin()+status); } bool Manage(int count,int t_PageId) //当内存已经满了需要按照三种算法调度时 { int status = searchStatusOfPage(t_PageId,false); //获取执行页面在外存中的索引地址 if(status == -1) return false; int targetStatus = 0; if(count == 0) targetStatus = findNeedLongestTimePage(); else if(count == 1) targetStatus = findLongestStayTimePage(); else if(count == 2) targetStatus = findLongestUnUseTimePage(); interPage[targetStatus].stayTime = 0; interPage[targetStatus].unUseTime = 0; swap(exterPage[status],interPage[targetStatus]); return true; } void Run(int count) //运行,通过 count 来决定使用什么算法 { while(presentSeat < 320) { for(unsigned i=0;i<interPage.size();i++) { interPage[i].stayTime++; interPage[i].unUseTime++;

27

} int t_PageId = findPageIdByCmdId(RunQueue[presentSeat++]),status = -1; //找到当前将要执 行的指令的页面号 if((status =searchStatusOfPage(t_PageId,true)) != -1) { interPage[status].unUseTime = 0; continue; } lackNum[count]++; if(interPage.size()<4) directFlod(t_PageId); else Manage(count,t_PageId); } } void main(void) //主函数 { InitDevice(); int count = 0; while(count<3) { InitMemoryQueue(); Run(count); cout<<(double)lackNum[count++]/320*100<<"%"<<endl; } }

【实验结果与分析】
缺页率分别为

28

【实验思考及总结】 首先,我们清楚一个概念:缺页——我要装的程序的页,内存中没有该页就叫缺页。 先进先出页面置换算法 往内存的 3 个页中先后装入程序的 3 个页(这三个的程序页号是不一样的) ,再装入程序的 下一个页时,先判断内存中有无此页,有就不用再次装入;内存中没有此页时,就把先进入 内存中的程序页给弄到虚拟内存上,然后,装入要装入的,以后,以此类推。 最近最久未使用置换算法 往内存的 3 个页中先后装入程序的 3 个页(这三个的程序页号是不一样的) ,再装入程序的 下一个页时,先判断内存中有无此页,有就不用再次装入;内存中没有此页时,就把内存中 那个隔得时间最长没有运行的程序页给弄到虚拟内存上,然后,装入要装入的,以后,以此 类推。这个开始时和先进先出页面置换算法的结果时一样的,但是,往后运行一段后,就不 一样了。 最佳置换算法 往内存的 3 个页中先后装入程序的 3 个页(这三个的程序页号是不一样的) ,再装入程序的 下一个页时,先判断内存中有无此页,有就不用再次装入;内存中没有此页时,该算法会把 之后要装入内存的程序页号查一遍,并且要计算出,此时内存中的三个页号在之后谁是被最 晚再次装入的页号,然后,把该页号给弄到虚拟内存上,然后,装入该装入的程序页号,最 佳置换算法是这几种算法中最好的算法。

先进先出适应算法特点:那个页面先进来,那个页面先出去,不管该页面是不是最近又被访 问了一次没有。这种算法连蒙都不会。

29

最长最久未被使用算法的特点:页面置换时,不管你们这些页面谁先进来,我只管的是从你 们当中选择一个从最后一次被访问到现在,时间最长的那个页面。这个比较会蒙。 最佳适应算法:置换页面的时候,我看一下以后要进来的页面,把那个最晚再次进入内存的 页面(这些页面必须是内存中存在的那些)置换出来。这个是铁板钉钉的事

30


网站首页 | 网站地图
All rights reserved Powered by 酷我资料网 koorio.com
copyright ©right 2014-2019。
文档资料库内容来自网络,如有侵犯请联系客服。3088529994@qq.com