内存管理


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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值