计算机操作系统Word格式文档下载.docx
《计算机操作系统Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《计算机操作系统Word格式文档下载.docx(15页珍藏版)》请在冰豆网上搜索。
4.Windows进程的虚拟地址空间中也有三种状态的页面:
空闲页面、保留页面和提交页面。
(1)空闲(Free)页面:
空闲页面是指那些可以保留或提交的可用页面。
(2)保留(Reserved)页面:
保留页面是逻辑页面已分配但没有分配物理存储的页面。
设置这种状态的效果是可以保留一部分虚拟地址,这样,如果不预先释放这些地址,就不能被其他应用程序(如Malloc,LocalAlloc等)的操作所使用。
试图读或写空闲页面或保留页面将导致页面出错异常。
保留页面可被释放后提交。
(3)提交(Committed)页面:
提交页面是物理存储(在内存中或磁盘上)已被分配的页面。
可对它加以保护,不许访问或允许只读访问,或允许读写访问。
提交也可以被回收以释放存储空间,从而变成保留页面。
四设计详细要求
使用windows2000/XP的API函数,编写一个包含两个线程的进程,一个线程用于模拟内存分配活动,一个线程用于跟踪第一个线程的内存行为,而且要求两个线程之间通过信号量实现同步。
模拟内存活动的线程可以从一个文件中读出要进行的内存操作,每个内存操作包括以下内容:
·
时间:
操作等待时间。
块数:
分配内存的粒度。
操作:
包括保留(reserve)一个区域,提交(commit)一个区域,释放(release)一个区域,回收(decommit)一个区域和加锁(lock)与解锁(unlock)一个区域,可以将这些操作编号存放于文件。
保留时之保留进程的虚拟地址空间,而不分配物理存储空间。
提交在内存中分配物理存储空间。
回收是指释放物理内存空间,但在虚拟地址空间仍然保留,它与提交相对应,即可以回收已经提交的内存块。
释放是指将物理存储和虚拟地址空间全部释放,它与保留相对应,即可以释放已经保留的内存块。
大小:
块的大小。
访问权限:
共五种。
分别为PAGE_READONLY,PAGE_READWRITE,PAGE_EXECUTE,AGE_EXECUTE_READ和PAGE_EXETUTE_READWRITE。
可以将这些权限编号存放于文件中跟踪线程将页面大小、已使用的地址范围、物理内存总量,以及虚拟内存总量等信息显示出来。
五课程设计说明
5-1模块组成:
本程序主要由文件建立和文件写入模块—makefile和内存操作模块--memory-op两大模块组成。
5-2模块的主要功能及结构:
(1)文件建立和文件写入模块makefile模块的主要功能及结构如下:
作用:
本程序主要实现将操作写入文件
结构:
本程序采用了C语言的fwrite函数直接以结构(struct)为单位写入文件。
用了两层循环,外层循环控制对内存的操作(保留、提交、锁、解锁、回收、释放),内层循环控制对内存操作的权限(PAGE_READONLY、PAGE_READWRITE、PAGE_EXECUTE、PAGE_EXECUTE_READ、PAGE_EXECUTE_READWRITE)用随机数生成等待执行的时间和分配的粒度。
(2)内存操作模块memory-op模块的主要功能及结构如下:
2.2.1主函数
a、创建两个线程,并将返回的句柄存入数据中。
b、创建两个信号量(allo,trac)分别用语通知跟踪线程和记录线程。
c、用函数WaitForMultipleObjects来等待两个线程的结束。
2.2.2Tracker线程(记录内存的状况)
a、打开文件,准备输出。
b、等待现成Allocator的一次内存操作完毕(即等待信号量trac的释放)。
c、用函数GetSystemInfo得到系统信息(该信息不随内存分配的变化而变化)。
d、用函数GlobalMemorySatus得到内存信息(随内存的分配各项信息会有所变化)。
用函数VirtualQuery得到虚拟内存基本信息(该信息不随内存分配的变化而变化)。
e、释放信号量,通知Allocator线程可以进行下一次内存分配活动。
2.2.3Allocator线程(模拟内存分配活动)
a、打开文件(的输出结果),准备读入。
b、等待Tracker输出的结束(即等待信号量allo的释放)。
c、读文件(的输出结果)。
d、根据文件内容(protection)确定对内存操作时的权限。
e、根据文件内容(oper)确定对内存的具体操作。
f、释放信号量(trac)通知线程可以进行一次输出。
g、如果文件中所有的分配信息已经完成,线程退出,否则转到b。
5-3程序流程图及分析:
makefile函数:
先创建一个文件“opfile”,用以确定内存操作信息,随后用两层循环实现对文件写入内存操作的具体信息和结构。
memory_op函数:
主函数main主要是生成两个线程和两个信号量,最后用函数WaitForMultipleObjects来等待两个线程的结束,退出程序。
用信号量trac个allo实现线程Tracker和Allocator的同步。
Tracker线程主要用于跟踪内存分配情况并打印信息到文档中,所以Tracker中首先要创建一个输出文件,然后输出系统消息、内存状态等。
Allocator线程用于内存分配及操作等。
首先要从opfile文件中逐个读取信息,其次根据内容确定操作权限,用switch语句实现:
0代表只读,1代表可读写,2代表可执行,3代表可执行可读,4代表可执行可读写。
然后确定内存具体操作,用switch实现:
0代表保留一个区域,用函数VirutalAlloc实现;
1代表提交一个区域,用函数VirtualAlloc实现;
2代表锁一个区域,用函数VirtualLock实现;
3代表解锁一个区域,用函数VirtualUnlock实现;
4代表回收一个区域,用函数VirtualFree实现;
5代表释放一个区域,用函数VirtualFree实现。
makefile函数和memory_op主函数:
memory_op:
创建线程Tracker,Allocator
创建信号量trac,allo
两线程执行完毕?
N
Y
结束
开始
接下页:
makefile函数:
创建文件opfile
修改操作信息
将信息写入文件
所有信息写入完毕?
tracker函数:
如下页:
建立输出文件
Allocator的一次操作结束?
输出信息到
所有的记录结束?
tracker函数
allocator函数:
如下页
读文件opfile
Tracker一次显示结束?
确定操作权限
执行操作
所有操作执行完毕?
Allocator函数
六课程设计主要源代码
1.makefile函数程序的代码及注释如下:
程序体:
#include<
fstream.h>
stdio.h>
stdlib.h>
time.h>
structoperation
{inttime;
//起始时间
intblock;
//内存页数
intoper;
//操作
intprotection;
//权限
};
intmain()
{FILE*file;
file=fopen("
opfile"
"
wb"
);
//"
为二进制用以确定内存操作
operationop;
for(intj=0;
j<
6;
j++)//0-保留;
1-提交;
2-锁;
3-解锁;
4-回收;
5-释放
for(inti=0;
i<
5;
i++)
{op.time=rand()%1000;
//随机生成等待时间
op.block=rand()%5+1;
//随机生成块大小
op.oper=j;
op.protection=i;
fwrite(&
op,sizeof(operation),1,file);
//将生成的结构写入文件
}
return0;
}
2.memeroy_op函数程序的代码及注释如下:
windows.h>
iostream.h>
structtrace//跟踪每一次分配活动的数据结构
{
LPVOIDstart;
//起始地址
longsize;
//分配的大小
HANDLEallo,trac;
//信号量句柄
DWORDTracker(LPDWORDlpdwparm)
ofstreamoutfile;
//输出文件
("
"
for(inti=0;
=30;
{
WaitForSingleObject(trac,INFINITE);
//等待allocator一次内存分配活动结束
//打印所有内存状况和系统状况
outfile<
<
endl;
//以下一段显示系统消息,每次执行操作后系统消息不变
//如果要才查看系统消息,可以取消注释
/*SYSTEM_INFOinfo;
//系统消息
GetSystemInfo(&
info);
outfile<
dwActiveProcessorMask"
'
\t'
iveProcessorMask<
dwAllocationGranularity"
info.dwAllocationGranularity<
dwNumberOfProcessors"
info.dwNumberOfProcessors<
dwOemId"
Id<
dwPageSize"
eSize<
dwProcessorType"
cessorType<
lpMaximumApplicationAddress"
info.lpMaximumApplicationAddress<
lpMinimumApplicationAddress"
info.lpMinimumApplicationAddress<
wProcessorArchitecture"
essorArchitecture<
wProcessorLevel"
essorLevel<
wProcessorRevision"
essorRevision<
wReserved:
rved<
********************************************************"
*/
//内存状况
MEMORYSTATUSstatus;
//内存状态
GlobalMemoryStatus(&
status);
dwAvailPageFile"
ilPageFile<
dwAvailPhys"
ilPhys<
dwAvailVirtual"
ilVirtual<
dwLength"
gth<
dwMemoryLoad"
oryLoad<
dwTotalPageFile"
alPageFile<
dwTotalPhy"
alPhys<
dwTotalVirtual"
alVirtual<
&
//以下一段显示内存基本信息,每次操作内存基本信息不变
//如果要查看内存基本信息,可以取消注释
/*MEMORY_BASIC_INFORMATIONmen;
VirtualQuery(imumApplicationAddress,&
men,sizeof(MEMORY_BASIC_INFORMATION));
AllocationBase"
ationBase<
AllocationProtect"
ationProtect<
BaseAddress"
ddress<
Protect"
ct<
RegionSize"
nSize<
State"
Type"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
*///释放信号量通知allocator可以进行下一次内存分配活动
ReleaseSemaphore(allo,1,NULL);
}
return(0);
voidAllocator()//模拟内存分配活动的线程
tracetraceArray[5];
intindex=0;
FILE*file;
rb"
//读入文件
SYSTEM_INFOinfo;
DWORDtemp;
30;
WaitForSingleObject(allo,INFINITE);
//等待tracker打印结束的信号量
cout<
:
;
fread(&
Sleep(op.time);
//执行时间,如果想在指定时间执行可以取消注释
GetSystemInfo(&
switch(op.protection)//根据文件内容确定权限
{
case0:
{
index=0;
temp=PAGE_READONLY;
break;
}
case1:
temp=PAGE_READWRITE;
break;
case2:
temp=PAGE_EXECUTE;
case3:
temp=PAGE_EXECUTE_READ;
case4:
temp=PAGE_EXECUTE_READWRITE;
default:
temp=PAGE_READONLY;
switch(op.oper)
//保留一个区域
cout<
reservenow"
traceArray[index].start=VirtualAlloc(NULL,op.block*eSize,MEM_RESERVE,PAGE_NOACCESS);
traceArray[index++].size=op.block*eSize;
startingaddress:
traceArray[index-1].start<
/t'
size:
traceArray[index-1].size<
case1:
//提交一个区域
commitnow"
traceArray[index].start=VirtualAlloc(traceArray[index].start,traceArray[index].size,MEM_COMMIT,temp);
index++;
}
//锁一个区域
locknow"
traceArray[index].start<
traceArray[index].size<
if(!
VirtualLock(traceArray[index].start,traceArray[index++].size))
cout<
GetLastError()<
//GetLastError()函数返回错误号
//解锁一个区域
unlocknow"
VirtualUnlock(traceArray[index].start,traceArray[index++].size))
case4:
//回收一个区域
decommitnow"
if(!
VirtualFree(traceArray[index].start,traceArray[index++].size,MEM_DECOMMIT))
case5:
//释放一个区域
releasenow"
VirtualFree(traceArray[index++].start,0,MEM_RELEASE))
cout<
error"
ReleaseSemaphore(trac,1,NULL);
//释放信号量通知tracker可以打印信息
{DWORDdwThread;
HANDLEhandle[2];
//生成两个线程
handle[0]=C