Windows页面置换算法与文件操作

news/2024/10/18 5:53:59/

实验一

一、实验内容或题目:

随机产生页面访问序列,并实现LRU, FIFO, OPT三种算法进行缺页比较

二、实验目的与要求:

1、编写程序,随机产生页面访问序列,并实现LRU, FIFO, OPT三种算法进行缺页比较。
2、理解三种算法的机制及优劣点。
3、理解belady现象

三、实验步骤:

1、在pagefault.c基础上实现三种算法。
2、运行并比较三种算法的缺页次数
3、通过固定srand函数的种子,并调节MEMORY_SIZE大小以及随机实验,尝试让FIFO算法出现belady现象

四、实验结果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

五、总结:

由于期末临近,实在是没有时间来完成这个实验,在GitHub上找了一个作者的代码进行了阅读,LRU, FIFO, OPT三个算法思路还是比较清晰的,当然OPT是无法跑的,作者用了数据结构的方式来实现这三个方式,读起来有些复杂的,但思路还是很清晰的。如果自己写还是比较难写出来的,这个需要考虑的东西会很多,很容易出错。

算法规则特点
OPT优先淘汰最长时间内不会被访问的页面缺页率最小,性能最好,但无法实现
FIFO优先淘汰最先进入内存的页面实现简单,但性能很差,可能出现Belady异常
LRU优先淘汰最近最久没访问的页面性能很好,但需要硬件支持,算法开销大

Belady现象是指当进程分配的物理块数增大时,缺页次数不减反增的异常现象。

六、源码

#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <time.h>#define total_instruction 320 //指令流长(指令数量)
#define total_vp 32 //虚页长(虚拟空间大小)
#define INVALID -1
#define TRUE 1
#define FALSE 0#define clear_period 50 //清零周期(NUR)typedef struct
{int pn; //page numberint pfn; //page_frame numberint counter; //访问记录(LFU、NUR)int time; //访问时间(LRU)
}pl_type;//页面结构体(进程)
pl_type pl[32];//32个虚存页面typedef struct pfc_struct
{int pn, pfn;struct pfc_struct* next;
}pfc_type;//页框结构体(内存)
pfc_type pfc[32], * freepf_head, * busypf_head, * busypf_tail;int diseffect; //缺页次数
int a[total_instruction]; //地址序列
int page[total_instruction]; //页号
int offset[total_instruction]; //页内偏移void generate_inst_addr_sq() { //生成地址序列int s, i;srand(time(NULL)); //设置随机数种子s = (float)319 * rand() / RAND_MAX + 1; //0-319随机数for (i = 0; i < total_instruction; i += 4){if (s < 0 || s>319){printf("When i==%d, Error, s==%d\n", i, s);exit(0);}a[i] = s; //任意一指令访问点a[i + 1] = a[i] + 1; //顺序执行一条指令a[i + 2] = (float)a[i] * rand() / RAND_MAX; //执行前指令ma[i + 3] = a[i + 2] + 1; //顺序执行一条指令s = (float)(318 - a[i + 2]) * rand() / RAND_MAX + a[i + 2] + 2;if ((a[i + 2] > 318) || (s > 319))printf("a[%d+2], a number which is: %d and s==%d", i, a[i + 2], s);}for (i = 0; i < total_instruction; i += 4)printf("%03d, %03d, %03d, %03d\n", a[i], a[i + 1], a[i + 2], a[i + 3]);for (i = 0; i < total_instruction; i++){//将地址转换为页号、页内偏移,每个页面大小为10page[i] = a[i] / 10;offset[i] = a[i] % 10;}
}void initialize(int total_pf)
{int i;diseffect = 0;for (i = 0; i < 32; i++){pl[i].pn = i;pl[i].pfn = INVALID;pl[i].counter = 0;pl[i].time = -1;}for (i = 0; i < total_pf - 1; i++){pfc[i].next = &pfc[i + 1];pfc[i].pfn = i;}pfc[total_pf - 1].next = NULL;pfc[total_pf - 1].pfn = total_pf - 1;freepf_head = &pfc[0]; //freepf_head总是指向可用页框
}void FIFO(int total_pf)
{int i, j;pfc_type* p;initialize(total_pf);busypf_head = busypf_tail = NULL;for (i = 0; i < total_instruction; i++){if (pl[page[i]].pfn == INVALID){diseffect += 1;if (freepf_head == NULL) //没有空闲页框{//释放忙页框队列中的第一个页面框p = busypf_head->next;pl[busypf_head->pn].pfn = INVALID; //原来页取消所在页框freepf_head = busypf_head;freepf_head->next = NULL; //处理p=freepf_head->next,之后保持没有空闲页框busypf_head = p; //更新忙页框队列起点}//freepf所示页框填入页面p = freepf_head->next; //暂存下一个可能空闲的页框freepf_head->next = NULL;freepf_head->pn = page[i];pl[page[i]].pfn = freepf_head->pfn;/*将freepf页框插入忙队列尾*/if (busypf_tail == NULL) //忙页框队列为空(仅执行一次)busypf_head = busypf_tail = freepf_head;else{busypf_tail->next = freepf_head;busypf_tail = freepf_head;}freepf_head = p;}}printf("FIFO:%6.4f ", 1 - (float)diseffect / 320);
}void LRU(int total_pf)
{int min, minj, i, j, present_time;initialize(total_pf);present_time = 0;for (i = 0; i < total_instruction; i++){if (pl[page[i]].pfn == INVALID){diseffect++;if (freepf_head == NULL) //没有空闲页框,需替换{   //找到time最小的页,并释放其页框min = 32767;for (j = 0; j < 32; j++){if (min > pl[j].time && pl[j].pfn != INVALID) //页框队列中time最小的页面{min = pl[j].time;minj = j;}}//其页框进入free_pf,撤销time最小的页面freepf_head = &pfc[pl[minj].pfn];pl[minj].pfn = INVALID;pl[minj].time = -1;freepf_head->next = NULL; //处理freepf_head=freepf_head->next,之后保持没有空闲页框}//新页换入freepf中的第一个页框pl[page[i]].pfn = freepf_head->pfn;pl[page[i]].time = present_time;freepf_head = freepf_head->next;}elsepl[page[i]].time = present_time; //忙页框队列中命中,更新timepresent_time++;}printf("LRU:%6.4f ", 1 - (float)diseffect / 320);
}void OPT(int total_pf)
{int i,j , max, maxpage, d, dist[total_vp];pfc_type *t;initialize(total_pf);for(i=0;i<total_instruction;i++){if(pl[page[i]].pfn==INVALID){diseffect++;if(freepf_head==NULL){for(j=0;j<total_vp;j++)if(pl[j].pfn!=INVALID)dist[j]=32767;elsedist[j]=0;d=1;for(j=i+1;j<total_instruction;j++){if(pl[page[j]].pfn!=INVALID)dist[page[j]]=d;d++;}max=-1;for(j=0;j<total_vp;j++)if(max<dist[j]){max=dist[j];maxpage=j;}freepf_head=&pfc[pl[maxpage].pfn];freepf_head->next=NULL;pl[maxpage].pfn=INVALID;}pl[page[i]].pfn=freepf_head->pfn;freepf_head=freepf_head->next;}}printf("OPT:%6.4f ",1-(float)diseffect/320);
}int main()
{int i;generate_inst_addr_sq();for (i = 4; i <= 32; i++) //物理内存容量:4-32个页框{printf("%2d page frames\t", i);FIFO(i);LRU(i);//OPT(i);printf("\n");}return 0;
}

实验二

一、实验内容或题目:

通用调用操作系统API,实现对文件的创建和异步读取操作。

二、实验目的与要求:

1、通用调用操作系统API,实现对文件的创建和异步读取操作
2、了调文件系统中的一些常用参数应用
3、编写程序实现并理解I/O设备的异步访问

三、实验步骤:

1、编写createAndExpandFile函数,在指定位置创建文件并扩展到1M长度
2、编写getFileContentAsync函数,异步读取文件内容。内容并无意义,读到缓冲区中即可,但要求使用异步读取,主函数在发起异步请求后等待在事件上,等异步完成后回调再唤醒。
需要使用的api:
CreateFile, SetEndOfFile, SetFilePointer, ReadFile, WaitEvent

四、实验结果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

五、总结

根据官网的指示,要使用SetEndOfFile才能实现文件的扩展。由于官网并没有给实例代码,查了很多资料才知道怎么写。通过将SetFilePointer调用到所需位置,然后通过SetEndOfFile截断到所需位置,就可以实现文件长度的扩展。
在这里插入图片描述
在这里插入图片描述
在第二个实验上,通过事件内核对象,可以支持多个异步io。每个read或者write里面的overlapped的结构,可以设置一个事件内核对象,这样每次io的事件内核对象是不一样的,就可以支持多个异步io了。

六、源码

#include <Windows.h>
#include <stdio.h>
#include <winerror.h>#define FILE_NAMEA	TEXT(FILE_NAME)HANDLE hEvent;/**
在此函数中创建FILE_NAME并将之扩展到1MB大小
注意:
1)创建文件时使用TRUNCATE_EXSITING标识
2)传参时使用FILE_NAMEA
**/
void createAndExpandFile() {LPCTSTR lpfname = TEXT("C://Users//86133//Desktop//text.tmp");LONG lsize = 1000000; // 1MBDWORD dwErr;HANDLE file = CreateFile(lpfname,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_NEW | OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);dwErr = GetLastError();if (dwErr > 0) {printf("Error Code:%d", &dwErr);}SetFilePointer(file, lsize, 0, FILE_BEGIN);SetEndOfFile(file);CloseHandle(file);
}/**
在此函数中打开创建的文件,读出其所有内容到一个缓冲区中
使用异步读,在读回调函数里使用hEvent通知主函数继续运行
**/
void getFileContentAsync() {HANDLE hFile = CreateFileW(L"C://Users//86133//Desktop//text.tmp", GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);//打开前面创建的文件BYTE buffer[10] = { 0 };OVERLAPPED ol = { 0 };ol.Offset = 0;HANDLE hEvent = CreateEvent(0, FALSE, FALSE, NULL);ol.hEvent = hEvent;//传递一个事件对象。BOOL rt = ReadFile(hFile, buffer, 7, NULL, &ol);//提交一个异步读操作if (rt == FALSE && GetLastError() == ERROR_IO_PENDING){WaitForSingleObject(ol.hEvent, INFINITE);//等待事件对象被触发。}CloseHandle(hFile);CloseHandle(hEvent);
}int main() {hEvent = CreateEvent(NULL,               // default security attributesTRUE,               // manual-reset eventFALSE,              // initial state is nonsignaledNULL  // object name);createAndExpandFile();getFileContentAsync();
}

http://www.ppmy.cn/news/533588.html

相关文章

尚硅谷大数据Flink1.17实战教程-笔记02【Flink部署】

尚硅谷大数据技术-教程-学习路线-笔记汇总表【课程资料下载】视频地址&#xff1a;尚硅谷大数据Flink1.17实战教程从入门到精通_哔哩哔哩_bilibili 尚硅谷大数据Flink1.17实战教程-笔记01【Flink概述、Flink快速上手】尚硅谷大数据Flink1.17实战教程-笔记02【Flink部署】尚硅谷…

小白也会的------新建Python虚拟环境,查看该虚拟环境的路径,将该虚拟环境的所有库和版本号导出到一个 requirements.txt 文件中

我的目录标题 1、新建Python虚拟环境2、查看该虚拟环境的路径3、将该虚拟环境的所有库和版本号导出到一个 requirements.txt 文件中4、如果你只需要将当前虚拟环境中安装的所有库和版本号导出到一个 requirements.txt 文件中&#xff0c;而不需要包括每个库的来源&#xff0c;可…

基于YOLOv8模型+CnOCR识别技术实现汽车车牌识别

目录 第1步:导入库 第2步:训练数据集下载 训练\验证\测试分割 第2步:数据探索 示例图像

有什么平价好用的蓝牙耳机?500内最强蓝牙耳机点评

无线蓝牙耳机早已取代有线耳机在人们心目中的地位。无线蓝牙耳机的使用非常方便&#xff0c;不仅不会被有线耳机那样束缚着&#xff0c;在开车、工作、娱乐的时候&#xff0c;无线蓝牙耳机都能无限制的使用&#xff0c;那么市场上的蓝牙耳机各式各样&#xff0c;有什么平价好用…

适合女生的蓝牙耳机有哪些?四款高颜值蓝牙耳机推荐

现如今&#xff0c;科技产品和智能设备已经紧紧将我们包围&#xff0c;因工作或生活上的原因&#xff0c;很多童鞋手上都拥有多台设备。现在蓝牙耳机越来越成为我们使用耳机的主流类型&#xff0c;很多人也想拥有一款好用的蓝牙耳机&#xff0c;但是又不知道如何挑选&#xff0…

跑步健身戴什么耳机合适?五款高性价比运动耳机推荐

非常多的运动者本身同时也是一个音乐爱好者&#xff0c;他们都有着边听音乐边运动的习惯&#xff0c;无论是长短跑、游泳还是其他运动都少不了音乐的陪伴。因为随着耳机里的音乐播放&#xff0c;会给他们带来不单单只是埋头跑步所体验不了的快乐感。市面上那么多的运动耳机&…

双十一潮流好物运动耳机分享,最热门的运动耳机推荐

​耳机逐渐成为现代青年必备的一款社交数码产品&#xff0c;特别是运动耳机&#xff0c;很多人都回佩戴着耳机跑步健身&#xff0c;显然&#xff0c;想要找到一款适合自己的运动耳机对于新手来说&#xff0c;确实有点难找&#xff0c;但对于我们这种运动爱好者来说就很简单了&a…

蓝牙知识介绍

这篇文章介绍主要就蓝牙的一些基本知识---起源&#xff0c;发展历程&#xff0c;协议栈和蓝牙的一些简单应用&#xff0c;对蓝牙未来的发展做个简单介绍。 一、蓝牙的起源 公元940-985年&#xff0c;哈洛德.布美塔特(Harald Blatand)&#xff0c;后人称Harald Bluetooth&#x…