内存管理
来源:互联网 发布:新丰网络问政平台 编辑:程序博客网 时间:2024/06/15 22:03
1.题目要求
编写一个程序,包括两个线程,一个线程用于模拟内存分配活动,另一个用于跟踪第一个线程的内存行为,要求两个线程之间通过信号量实现同步,模拟内存活动的线程可以从一个文件中读出要进行的内存操作。每个内存操作包含如下内容:
时间:每个操作等待时间;
块数:分配内存的粒度;
操作:包括保留一个区域、提交一个区域、释放一个区域、回收一个区域、加锁与解锁一个区域。可将它们的编号放置于一个文件中。
保留是指保留进程的虚地址空间,而不分配物理地址空间;
提交是指在内存中分配物理地址空间;
回收是指释放物理地址空间,而保留进程的虚地址空间;
释放是指将进程的物理地址与虚拟地址空间全部释放;
大小:块的大小;
访问权限:共五种PAGE_READONLY, PAGE_READWRIYE, PAGE_EXEXUTE, PAGE_EXEXUTE _READ, PAGE_EXEXUTE _READWRIYE.
2.测试样例随机生成
定义操作和权限的方式采用了两层循环,外层循环控制对内存的操作,内层循环控制对内存的权限。随机生成。
#include <iostream>#include <stdlib.h>#include "fstream"using namespace std;struct operation{ int time; //起始时间 int block;//内存页数 int oper; //操作 int protection;//权限};int main(){ FILE *file ; file=fopen("file","wb");//opfile为二进制,用于确定内存操作 operation op; for(int j=0; j<6; j++) //0-保留;1-提交;2-锁;3-解锁;4-回收;5-释放 for(int i = 0; i<5; i++) /*0-PAGE_READONL 1-PAGE_WRITE 2-PAGE_EXECUTE 3-PAGE_EXECUTE_READ 4-PAGE_EXECUTE_READWRITE*/ { op.time=rand()%1000; //随机生成等待时间 op.block=rand()%5+1;//随机生成块 op.oper=j; op.protection=i; fwrite(&op,sizeof(operation),1,file);//将生成的结果写入文件 } return 0;}
3.详细设计
主函数模块
1.创建两个线程,并将返回的句柄存入数组中。
handle[0]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Tracker,NULL,0,&dwThread);
handle[1]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Allocator,NULL,0,&dwThread);
2.创建两个信号量(allo,trac)分别用来通知跟踪线程和记录线程。
allo=CreateSemaphore(NULL,0,1,"allo");
trac=CreateSemaphore(NULL,0,1,"trac");
3.用函数WaitForMultipleObjects等待两个线程的结束。
跟踪线程的内存行为,并输出必要信息子模块
1.打开文件out.txt准备输出。
2.等待线程Allocator的一次内存操作完毕(即等待信号量trac的释放)。WaitForSingleObject(trac,INFINITE);
3.用函数SYSTEM_INFO info ; GetSystemInfo(&info);获得系统信息。
4.用MEMORYSTATUS status ;GlobalMemoryStatus(&status);得到内存信息。用函数VirtualQuery得到虚拟内存的基本信息。
5.释放信号量,通知Allocator线程可以进行下一步的分配活动。
6.如果硬件记录了所有的内存分配情况则线程退出,否则转到第2步。
模拟内存分配活动的线程子模块
1.打开文件(file)准备读入文件内容。
2.等待Tracker输出的结束(等待信号量allo释放)。
3.读文件(file)。
4.根据文件内容(protection)确定对内存的操作的权限。
5.根据文件内容(oper)确定对内存的具体操作。
6.释放信号量(trac)通知Tracker线程可以进行一次输出 。
7.如果文件中的所有分配信息已经完成,线程退出,否则转到第2步。
4.代码
#include <iostream>#include <stdlib.h>#include <windows.h>#include "fstream"using namespace std;struct operation{ int time;//起始时间 int block;//内存页数 int oper;//操作 int protection;//权限};struct trace{ LPVOID start;//起始地址 long size;//分配的大小};HANDLE allo,trac;DWORD Tracker(LPDWORD lpdwparm)//跟踪线程的内存行为,并输出必要信息{ ofstream outfile; outfile.open("out.txt"); for(int i=0; i<=30; i++) { WaitForSingleObject(trac,INFINITE);//等待allocator一次内存分配活动结束 //打印内存状况和系统状况 outfile<<i<<endl; SYSTEM_INFO info;//系统信息 GetSystemInfo(&info); outfile<<"页面文件大小"<<'\t'<<info.dwPageSize<<endl; outfile<<"进程的最小内存地址"<<'\t'<<info.lpMinimumApplicationAddress<<endl; outfile<<"进程的最大内存地址"<<'\t'<<info.lpMaximumApplicationAddress<<endl; outfile<<"当前活动的CPU"<<'\t'<<info.dwActiveProcessorMask<<endl; outfile<<"CPU的个数"<<'\t'<<info.dwNumberOfProcessors<<endl; outfile<<"分配粒度"<<'\t'<<info.dwAllocationGranularity<<endl; outfile<<"当前处理器结构图"<<'\t'<<info.dwProcessorType<<endl; outfile<<"_______________________________________________________"<<endl; MEMORYSTATUS status;//内存状态 GlobalMemoryStatus(&status); outfile<<"MEMORYSTATUS结构的大小"<<'\t'<<status.dwLength<<endl; // sizeof(MEMORYSTATUS) outfile<<"系统内存的使用率"<<'\t'<<status.dwMemoryLoad<<endl; // percent of memory in use outfile<<"总的物理内存大小"<<'\t'<<status.dwTotalPhys<<endl; // bytes of physical memory outfile<<"可用的物理内存大小"<<'\t'<<status.dwAvailPhys<<endl; // free physical memory bytes outfile<<"显示可以存在页面文件中的字节数"<<'\t'<<status.dwTotalPageFile<<endl; // bytes of paging file outfile<<"可用的页面文件大小"<<'\t'<<status.dwAvailPageFile<<endl; // free bytes of paging file outfile<<"用户模式的全部可用虚拟地址空间"<<'\t'<<status.dwTotalVirtual<<endl; // user bytes of address space outfile<<"实际自由可用的虚拟地址空间"<<'\t'<<status.dwAvailVirtual<<endl; // free user bytes outfile<<"__________________________________________________"<<endl; //释放信号量通知allocator 可以执行下一次内存分配活动 ReleaseSemaphore(allo,1,NULL); } return 0;}void Allocator()//模拟内存分配活动的线程{ trace traceArray[5]; int index=0; FILE* file; file=fopen("file","rb");//读入文件 operation op; SYSTEM_INFO info; DWORD temp; GetSystemInfo(&info); for(int i=0; i<30; i++) { WaitForSingleObject(allo,INFINITE);//等待tracker打印结束的信号量 cout<<i<<endl; fread(&op,sizeof(operation),1,file); Sleep(op.time);//执行时间 GetSystemInfo(&info); switch(op.protection) { case 0: { index=0; temp=PAGE_READONLY; break; } case 1: temp=PAGE_READWRITE; break; case 2: temp=PAGE_EXECUTE; break; case 3: temp=PAGE_EXECUTE_READ; break; case 4: temp=PAGE_EXECUTE_READWRITE; break; default: temp=PAGE_READONLY; } switch(op.oper) { case 0: { cout<<"reserve now"<<endl; traceArray[index].start=VirtualAlloc(NULL,op.block *info.dwPageSize,MEM_RESERVE,PAGE_NOACCESS); traceArray[index++].size=op.block *info.dwPageSize; cout<<"strating address:"<<traceArray[index-1].start<<'\t'<<"size:"<<traceArray[index-1].size<<endl; break; } case 1: { cout<<"commit now"<<endl; traceArray[index].start=VirtualAlloc(traceArray[index].start,traceArray[index].size,MEM_COMMIT,temp); index++; cout<<"strating address:"<<traceArray[index].start<<'\t'<<"size:"<<traceArray[index].size<<endl; break; } case 2: { cout<<"lock now"<<endl; cout<<"strating address:"<<traceArray[index].start<<'\t'<<"size:"<<traceArray[index].size<<endl; if(!VirtualLock(traceArray[index].start,traceArray[index++].size)) cout<<GetLastError()<<endl; break; } case 3: { cout<<"unlock now"<<endl; cout<<"strating address:"<<traceArray[index].start<<'\t'<<"size:"<<traceArray[index].size<<endl; if(!VirtualUnlock(traceArray[index].start,traceArray[index++].size)) cout<<GetLastError()<<endl; break; } case 4: { cout<<"decommit now"<<endl; cout<<"strating address:"<<traceArray[index].start<<'\t'<<"size:"<<traceArray[index].size<<endl; if(!VirtualFree(traceArray[index].start,traceArray[index++].size,MEM_DECOMMIT)) cout<<GetLastError()<<endl; break; } case 5: { cout<<"release now"<<endl; cout<<"strating address:"<<traceArray[index].start<<'\t'<<"size:"<<traceArray[index].size<<endl; if(!VirtualFree(traceArray[index++].start,0,MEM_RELEASE)) cout<<GetLastError()<<endl; break; } default: cout<<"error"<<endl; } ReleaseSemaphore(trac,1,NULL); }}int main(){ DWORD dwThread; HANDLE handle[2]; handle[0]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Tracker,NULL,0,&dwThread); handle[1]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Allocator,NULL,0,&dwThread); allo=CreateSemaphore(NULL,0,1,"allo"); trac=CreateSemaphore(NULL,1,1,"trac"); WaitForMultipleObjects(2,handle,TRUE,INFINITE); return 0;}
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- QDataWidgetMapper QCheckBox ;qwt 的安装
- 第41题 Decode Ways
- [Be a Coding Plasterer] Components 1:get Basic Things
- Android开发插件 Eclipse ADT
- 二路归并 && 插入归并 && 原地归并
- 内存管理
- 字节序——大端(Big Endian)和小端(Little Endian)
- BASE64算法及应用
- JNI WARNING: negative jsize (NewByteArray)
- ASCII码排序
- 学习--mac下maven安装配置
- make 和 make install
- java String.intern()
- 不小心把Xcode里的头文件改写了怎么办