需求分析
编写一个程序,包括两个线程,一个线程用于模拟内存分配活动,另一个用于跟踪第一个线程的内存行为,要求两个线程之间通过信号量实现同步,模拟内存活动的线程可以从一个文件中读出要进行的内存操作。每个内存操作包含如下内容:
时间:每个操作等待时间;
块数:分配内存的粒度;
操作:包括保留一个区域、提交一个区域、释放一个区域、回收一个区域、加锁与解锁一个区域。可将它们的编号放置于一个文件中。
保留是指保留进程的虚地址空间,而不分配物理地址空间;
提交是指在内存中分配物理地址空间;
回收是指释放物理地址空间,而保留进程的虚地址空间;
释放是指将进程的物理地址与虚拟地址空间全部释放;
大小:块的大小;
访问权限:共五种PAGE_READONLY, PAGE_READWRIYE, PAGE_EXEXUTE, PAGE_EXEXUTE _READ, PAGE_EXEXUTE _READWRIYE.
设计思想
1.创建内存分配进程和内存跟踪进程。
内存分配进程接收用户输入的进程的开始时间、操作和访问权限, 并为其分配内存,虚拟地址和物理地址。
内存跟踪进程则负责输出进程的所有内存行为和信息。
2.创建两个信号量分别标志内存分配和跟踪。
内存分配信号量为1,则分配内存,进而使内存跟踪信号量为1来输出内存信息。内存分配信号量初始为1,内存跟踪信号量为0。
代码实现
#include <windows.h>
#include <bits/stdc++.h>
using namespace std;
const int maxn=10;
string option[5]= {"PAGE_READONLY","PAGE_READWRIYE","PAGE_EXEXUTE","PAGE_EXEXUTE _READ","PAGE_EXEXUTE _READWRIYE"};
string operation[5]= {"保留","提交","释放","回收","加锁"};
struct node
{
string starttime;
int div;
int opitionindex;
int size;
int limit;
int vitual_location=-1;
int physcial_site=-1;
} process[maxn];
int n;
HANDLE allo,trac;
DWORD Tracker(LPDWORD lpdwparm)//跟踪线程的内存行为,并输出必要信息
{
for(int i=0; i<n; i++)
{
WaitForSingleObject(trac,INFINITE);//等待allocator一次内存分配活动结束
Sleep(1000);
cout<<"--------------------"<<endl;
cout<<"进程块数:"<<process[i].div<<endl;
cout<<"内存大小:"<<process[i].size<<endl;
if(process[i].vitual_location==-1)
cout<<"虚拟地址:已被回收"<<endl;
else if(process[i].vitual_location==-2)
cout<<"虚拟地址:已加锁"<<endl;
else
cout<<"虚拟地址:"<<process[i].vitual_location<<endl;
if(process[i].physcial_site==0)
cout<<"物理地址:尚未分配"<<endl;
else if(process[i].physcial_site==-1)
cout<<"物理地址:已被回收"<<endl;
else if(process[i].physcial_site==-2)
cout<<"物理地址:已加锁"<<endl;
else
cout<<"物理地址:"<<process[i].physcial_site<<endl;
cout<<"权限:"<<option[process[i].limit]<<endl;
cout<<endl;
ReleaseSemaphore(allo,1,NULL);
}
ReleaseSemaphore(allo,1,NULL);
return 0;
}
void Allocator()//模拟内存分配活动的线程
{
for(int i=0; i<n; i++)
{
WaitForSingleObject(allo,INFINITE);//等待tracker打印结束的信号量
cout<<i+1<<endl<<"操作:"<<operation[process[i].limit]<<" "<<"开始时间:"<<setiosflags(ios::fixed)<<setprecision(2)<<process[i].starttime<<endl;
process[i].div=rand()%10+1;
process[i].size=rand()%65536;
process[i].vitual_location=i*1024+rand()%64+1;
if(process[i].opitionindex==0)
;
else if(process[i].opitionindex==1)
process[i].physcial_site=i;
else if(process[i].opitionindex==2)
process[i].vitual_location=-1;
else if(process[i].opitionindex==3)
process[i].physcial_site=-1;
else
process[i].physcial_site=process[i].vitual_location=-2;
ReleaseSemaphore(trac,1,NULL);
Sleep(1000);
}
ReleaseSemaphore(trac,1,NULL);
}
int main()
{
cout<<"请输入要模拟的进程数量"<<endl;
cin>>n;
cout<<"操作代号"<<endl<<"0--保留 1--提交 2--释放 3--回收 4--加锁"<<endl;
cout<<"权限代号"<<endl<<"0--PAGE_READONLY 1--PAGE_READWRIYE 2--PAGE_EXEXUTE 3--PAGE_EXEXUTE _READ 4--PAGE_EXEXUTE _READWRIYE"<<endl;
cout<<"----------------------------------------------------------------------------------------------------------"<<endl;
for(int i=0; i<n; i++)
{
cout<<"请输入第"<<i+1<<"个进程的开始时间、进行的操作和访问权限编号"<<endl;
cin>>process[i].starttime>>process[i].opitionindex>>process[i].limit;
}
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,1,1,"");
trac=CreateSemaphore(NULL,0,1,"");
WaitForMultipleObjects(2,handle,TRUE,INFINITE); //一参句柄数量,二参句柄数组,三参True,表示除非对象都发出信号,否则就一直等待下去;FALSE,表示任何对象发出信号即可
return 0; //指定要等候的毫秒数。如设为零,表示立即返回。如指定常数INFINITE,则可根据实际情况无限等待下去
}