编写一个程序,包括两个线程,一个线程用于模拟内存分配活动,另一个用于跟踪第一个线程的内存行为,要求两个线程之间通过信号量实现同步,模拟内存活动的线程可以从一个文件中读出要进行的内存操作。每个内存操作包含如下内容:
时间:每个操作等待时间;
块数:分配内存的粒度;
操作:包括保留一个区域、提交一个区域、释放一个区域、回收一个区域、加锁与解锁一个区域。可将它们的编号放置于一个文件中。
保留是指保留进程的虚地址空间,而不分配物理地址空间;
提交是指在内存中分配物理地址空间;
回收是指释放物理地址空间,而保留进程的虚地址空间;
释放是指将进程的物理地址与虚拟地址空间全部释放;
大小:块的大小;
访问权限:共五种PAGE_READONLY, PAGE_READWRIYE, PAGE_EXEXUTE, PAGE_EXEXUTE _READ, PAGE_EXEXUTE _READWRIYE.
#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;
}