内存管理

来源:互联网 发布:新丰网络问政平台 编辑:程序博客网 时间: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;}


0 0
原创粉丝点击