当前位置:文档之家› 请求分页存储管理模拟实验

请求分页存储管理模拟实验

操作系统模拟实验
实验名称:请求分页存储管理模拟实验
实验目的:通过实验了解windows系统中的线程同步如何使用,进一步了解操作系统的同步机制。

实验内容:调用Windows API,模拟解决生产者-消费者问题;思考在两个线程函数中哪些是临界资源?哪些代码是临界区?哪些代码是进入临界区?哪些代码是退出临界区?进入临界区和退出临界区的代码是否成对出现?学习Windows API中的如何创建线程,互斥,临界区等。

程序运行结果:
源程序:
#include "stdAfx.h"
//包含头文件以支持多线程
#include "windows.h"
#include "stdio.h"
//用于标志所有的子线程是否结束
//每次子线程结束后,此值便加1。

static long ThreadCompleted = 0;
//互斥量
HANDLE mutex;
//信号量,用于生产者通知消费者
HANDLE full;
//信号量,用于消费者通知生产者
HANDLE empty;
//信号量,当所有的子线程结束后,通知主线程,可以结束。

HANDLE evtTerminate;
//生产标志
#define p_item 1
//消费标志
#define c_item 0
//哨兵
#define END 10
//缓冲区最大长度
const int max_buf_size=11;
const int cur_size=10;
//缓冲区定义
int BUFFER[max_buf_size];
//放消息指针
int in=0;
//取消息指针
int out=0;
int front=0;
int tail=0;
int sleep_time=1000;
bool flag=true;
//线程函数的标准格式
unsigned long __stdcall p_Thread(void *theBuf);
unsigned long __stdcall c_Thread(void *theBuf);
//打印缓冲区内容
void PrintBuf(int buf[],int buf_size);
int main(int argc, char* argv[])
{
//初始化缓冲区
unsigned long TID1, TID2;
for(int i=0;i<cur_size;i++)
BUFFER[i]=0;
//互斥量和信号量的创建,函数用法可查看MSDN
mutex=CreateMutex(NULL,false,"mutex");
full=CreateSemaphore(NULL,0,1,"full");
empty=CreateSemaphore(NULL,max_buf_size,max_buf_size,"empty");
evtTerminate = CreateEvent(NULL, FALSE, FALSE, "Terminate");
//创建一个生产者线程和消费者线程。

作为本程序的扩展,你可以增加线程的数目
CreateThread(NULL,0,p_Thread,BUFFER,NULL,&TID1);
CreateThread(NULL,0,c_Thread,BUFFER,NULL,&TID2); while(flag)
{
if(getchar())
{flag=false;}
}
//等待各子线程的结束
WaitForSingleObject(evtTerminate, INFINITE);
return 0;
}
//生产者线程函数
unsigned long __stdcall p_Thread(void *theBuf)
{
while(flag)
{
Sleep(sleep_time);
//可以不要此函数,只是为了模拟缓冲区满的情况
if((front+1)%max_buf_size==tail)
{
printf("缓冲区已满,产品的线程被阻塞\n");
sleep_time+=3000;
}
WaitForSingleObject(empty,INFINITE);//先申请信号量
WaitForSingleObject(mutex,INFINITE);//再申请互斥量
/*进入临界区*/
printf("生产(线程)正在生产请等待\n");
BUFFER[in]=p_item;
in=(in+1)%cur_size;
front=(front+1)%max_buf_size;
PrintBuf(BUFFER,cur_size);
printf("我(生产者线程)已准备退出临界区\n");
//退出临界区
ReleaseMutex(mutex);
ReleaseSemaphore(full,1,0);
}
//线程结束后,将ThreadCompleted值加1
InterlockedIncrement(&ThreadCompleted);
if(ThreadCompleted ==2) SetEvent(evtTerminate);
return 0;
}
//消费者线程函数
unsigned long __stdcall c_Thread(void *theBuf)
{
while(flag)
{
Sleep(3000);
if(front==tail)
{
printf("缓冲区是空的\n");
sleep_time-=3000;
}
//P操作
WaitForSingleObject(full,INFINITE);
WaitForSingleObject(mutex,INFINITE);
printf("一个消费者进入critiction。

\n");
BUFFER[out]=c_item;
out=(out+1)%cur_size;
tail=(tail+1)%max_buf_size;
PrintBuf(BUFFER,cur_size);
printf("消费者已经离开critiction\n");
//V操作
ReleaseMutex(mutex);
ReleaseSemaphore(empty,1,0);
}
//同生产者进程
InterlockedIncrement(&ThreadCompleted);
if(ThreadCompleted ==2) SetEvent(evtTerminate);
return 0;
}
//打印缓冲区
void PrintBuf(int buf[],int buf_size)
{
int i;
printf("当前缓冲区状态:\n");
for(i=0;i<buf_size;i++)
printf("%d,",buf[i]);
printf("\n");
Sleep(1000);
//此函数是为了线程相临两次访问临界区时有序的打印缓冲区内容,//并不是必须的,你可以不要,但模拟的近似度就大打折扣了。

}。

相关主题