操作系统实验一.docx
《操作系统实验一.docx》由会员分享,可在线阅读,更多相关《操作系统实验一.docx(53页珍藏版)》请在冰豆网上搜索。
操作系统实验一
操作系统实验项目
一、处理器管理
实验目的和要求:
1、掌握操作系统中处理器管理的进程同步原理;
2、编写进程同步中的读者写者问题或生产者与消费者问题仿真程序;
3、分析实验结果,分析不同的同步机制对实验结果的影响。
实验项目及内容:
1、进程同步——读者写者问题
2、进程同步--生产者与消费者
3、进程调度
二、存储管理
实验目的和要求:
1、掌握操作系统中存储管理中分区、分段、分页管理的原理;
2、编写存储管理中动态分区方式的主存分配回收问题仿真程序;
3、熟悉虚存管理的各种页面淘汰算法;
4、加强对地址转换过程的了解;
5、分析实验结果,分析不同的分配方式存储器的利用效率。
实验项目及内容:
1、存储管理--动态分区方式的主存分配回收
2、分页式存储管理
3、虚拟内存技术
三、设备管理
实验目的和要求:
1、掌握操作系统中设备管理的数据结构和共享设备与独占设备的分配算法;
2、编写设备管理中共享设备磁盘调度的电梯调度仿真程序;
3、熟悉磁盘调度的各种算法;
4、分析各种调度算法的效率。
实验项目及内容:
四、文件管理
实验目的和要求:
1、掌握操作系统中文件管理中文件和目录的组织结构及文件操作方式;
2、编写文件管理中文件和目录操作实现程序,包括文件的建立、删除、打开、关闭、读、写操作程序和目录的建立、删除等操作子程序;
3、调用对应的实验程序实现文件和目录的相关操作。
实验目的和要求:
1、文件系统
实验1:
进程同步
实验1:
进程同步--读者写者问题
实验要求
在Windows2000环境下,创建一个包含n个线程的控制台进程。
用这n个线程来表示n个读者或写者。
每个线程按相应测试数据文件的要求,进行读写操作。
请用信号量机制分别实现读者优先和写者优先的读者-写者问题。
读者-写者问题的读写操作限制:
1)写-写互斥;
2)读-写互斥;
3)读-读允许;
读者优先的附加限制:
如果一个读者申请进行读操作时已有另一读者正在进行读操作,则该读者可直接开始读操作。
写者优先的附加限制:
如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。
运行结果显示要求:
要求在每个线程创建、发出读写操作申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确信所有处理都遵守相应的读写操作限制。
程序1:
测试数据文件格式
测试数据文件包括n行测试数据,分别描述创建的n个线程是读者还是写者,以及读写操作的开始时间和持续时间。
每行测试数据包括四个字段,各字段间用空格分隔。
第一字段为一个正整数,表示线程序号。
第二字段表示相应线程角色,R表示读者是,W表示写者。
第三字段为一个正数,表示读写操作的开始时间。
线程创建后,延时相应时间(单位为秒)后发出对共享资源的读写申请。
第四字段为一个正数,表示读写操作的持续时间。
当线程读写申请成功后,开始对共享资源的读写操作,该操作持续相应时间后结束,并释放共享资源。
下面是一个测试数据文件的例子:
1R35
2W45
3R52
4R65
5W5.13
与实验相关的API介绍
在本实验中可能涉及的API有:
线程控制:
CreateThread完成线程创建,在调用进程的地址空间上创建一个线程,以执行指定的函
数;它的返回值为所创建线程的句柄。
HANDLECreateThread(
LPSECURITY_ATTRIBUTESlpThreadAttributes,//SD
DWORDdwStackSize,//initialstacksize
LPTHREAD_START_ROUTINElpStartAddress,//thread
function
LPVOIDlpParameter,//threadargument
DWORDdwCreationFlags,//creationoption
LPDWORDlpThreadId//threadidentifier
);
ExitThread用于结束当前线程。
VOIDExitThread(
DWORDdwExitCode//exitcodeforthisthread
);
Sleep可在指定的时间内挂起当前线程。
VOIDSleep(
DWORDdwMilliseconds//sleeptime
);
信号量控制:
CreateMutex创建一个互斥对象,返回对象句柄;
HANDLECreateMutex(
LPSECURITY_ATTRIBUTESlpMutexAttributes,//SD
BOOLbInitialOwner,//initialowner
LPCTSTRlpName//objectname
);
OpenMutex打开并返回一个已存在的互斥对象句柄,用于后续访问;
HANDLEOpenMutex(
DWORDdwDesiredAccess,//access
BOOLbInheritHandle,//inheritanceoption
LPCTSTRlpName//objectname
);
ReleaseMutex释放对互斥对象的占用,使之成为可用。
BOOLReleaseMutex(
HANDLEhMutex//handletomutex
);
WaitForSingleObject可在指定的时间内等待指定对象为可用状态;
DWORDWaitForSingleObject(
HANDLEhHandle,//handletoobject
DWORDdwMilliseconds//time-outinterval
);
实验程序代码
#include
#include
#include
#include
#include
#include
#defineMAX_PERSON100
#defineREADER0
#defineWRITER1
#defineEND-1
#defineRREADER
#defineWWRITER
typedefstruct_Person
{
HANDLEm_hThread;
intm_nType;
intm_nStartTime;
intm_nWorkTime;
intm_nID;
}Person;
Persong_Persons[MAX_PERSON];
intg_NumPerson=0;
longg_CurrentTime=0;
intg_PersonLists[]={
1,R,5,5,
2,W,4,5,
3,R,2,2,
4,R,1,5,
END,
};
intg_NumOfReading=0;
HANDLEg_hReadMutex;
HANDLEg_hWriteMutex;
voidCheckPersonList(int*pPersonList);
boolCreateReader(intStartTime,intWorkTime);
boolCreateWriter(intStartTime,intWorkTime);
DWORDWINAPIReaderProc(LPVOIDlpParam);
DWORDWINAPIWriterProc(LPVOIDlpParam);
intmain()
{
g_hReadMutex=CreateMutex(NULL,FALSE,NULL);
g_hWriteMutex=CreateMutex(NULL,FALSE,NULL);
g_CurrentTime=0;
while(true)
{
CheckPersonList(g_PersonLists);
g_CurrentTime++;
Sleep(300);
printf("CurrentTime=%d\n",g_CurrentTime);
}
return0;
}
voidCheckPersonList(int*pPersonLists)
{
inti=0;
int*pList=pPersonLists;
boolRet;
while(pList[0]!
=END)
{
if(pList[2]==g_CurrentTime)
{
switch(pList[1])
{
caseR:
Ret=CreateReader(pList[2],pList[3]);
break;
caseW:
Ret=CreateWriter(pList[2],pList[3]);
break;
}
if(!
Ret)
printf("CreatePerson%diswrong\n",pList[0]);
}
pList+=4;//movetonextpersonlist
}
}
DWORDWINAPIReaderProc(LPVOIDlpParam)
{
Person*pPerson=(Person*)lpParam;
printf("Reader%disrequesttheSharedBuffer...\n",pPerson->m_nID);
WaitForSingleObject(g_hReadMutex,INFINITE);
if(g_NumOfReading==0)
{
WaitForSingleObject(g_hWriteMutex,INFINITE);
}
g_NumOfReading++;
ReleaseMutex(g_hReadMutex);
printf("Reader%disrequestok\n",pPerson->m_nID);
//modifythereader'srealstarttime
pPerson->m_nStartTime=g_CurrentTime;
printf("Reader%disReadingtheSharedBuffer...\n",pPerson->m_nID);
while(g_CurrentTime<=pPerson->m_nStartTime+pPerson->m_nWorkTime)
{
//..performreadoperations
}
printf("Reader%disExit...\n",pPerson->m_nID);
WaitForSingleObject(g_hReadMutex,INFINITE);
g_NumOfReading--;
if(g_NumOfReading==0)
ReleaseMutex(g_hWriteMutex);
ReleaseMutex(g_hReadMutex);
ExitThread(0);
return0;
}
DWORDWINAPIWriterProc(LPVOIDlpParam)
{
WaitForSingleObject(g_hWriteMutex,INFINITE);
Person*pPerson=(Person*)lpParam;
//modifythewriter'srealstarttime
pPerson->m_nStartTime=g_CurrentTime;
printf("Writer%disWrittingtheSharedBuffer...\n",pPerson->m_nID);
while(g_CurrentTime<=pPerson->m_nStartTime+pPerson->m_nWorkTime)
{
//..performwriteoperations
}
printf("Writer%disExit...\n",pPerson->m_nID);
ReleaseMutex(g_hWriteMutex);
ExitThread(0);
return0;
}
boolCreateReader(intStartTime,intWorkTime)
{
DWORDdwThreadID;
if(g_NumPerson>=MAX_PERSON)
returnfalse;
Person*pPerson=&g_Persons[g_NumPerson];
pPerson->m_nID=g_NumPerson;
pPerson->m_nStartTime=StartTime;
pPerson->m_nWorkTime=WorkTime;
pPerson->m_nType=READER;
g_NumPerson++;
//CreateanNewThread
pPerson->m_hThread=CreateThread(NULL,0,ReaderProc,(LPVOID)pPerson,0,&dwThreadID);
if(pPerson->m_hThread==NULL)
returnfalse;
returntrue;
}
boolCreateWriter(intStartTime,intWorkTime)
{
DWORDdwThreadID;
if(g_NumPerson>=MAX_PERSON)
returnfalse;
Person*pPerson=&g_Persons[g_NumPerson];
pPerson->m_nID=g_NumPerson;
pPerson->m_nStartTime=StartTime;
pPerson->m_nWorkTime=WorkTime;
pPerson->m_nType=WRITER;
g_NumPerson++;
//CreateanNewThread
pPerson->m_hThread=CreateThread(NULL,0,WriterProc,(LPVOID)pPerson,0,&dwThreadID);
if(pPerson->m_hThread==NULL)
returnfalse;
returntrue;
}
关于同步互斥的API探讨
WindowsAPI里面有两个方法可以实现同步互斥,一个是CreateMutex创建互斥信号,另外一个是CreateSemaphore创建一般信号量.上面的程序是实现一般的读者写者的同步互斥问题,按理来说使用Mutex是比较的选择,可是实际上面的程序运行的结果发现,当创建Mutex的线程结束后,其Mutex就自动释放(解开),即使这个时候没有使用ReleaseMutex函数.然后老师叫我使用CreateSemaphore来实现,测试发祥,使用Semaphore就没有这个问题.不知道这个问题是不是Windows系统故意这样设计的.
关于Windows实现的同步互斥的详细API介绍,请查看
程序2:
操作系统实验之读者-写者实现代码说明文档
/////////////////////////////////
读者-写者的读写限制(包括读者优先和写者优先)
1)写-写互斥,即不能有两个写者同时进行写操作
2)读-写互斥,即不能同时有一个读者在读,同时却有一个写者在写
3)读读允许,即可以有2个以上的读者同时读
读者优先的限制:
如果一个读者申请读操作时,已经有一个读者在读,则该读者可以直接读
写者优先的限制:
如果一个读者申请读操作时,有写者在等待访问共享资源时,则该读者要等到没有写者处于等的状态时才能开始读操作
/////////////////////////////////
测试数据的格式
在文件thread.dat中,
1r35
2w45
....
其中第一个代表线程的ID,第二个字段代表是读操作还是写操作,第三个字段代表操作的开始时间,第4个字段是持续时间。
/////////////////////////////////
分析:
将所有的读者和所有的写者分别放进两个等待队列中,当读允许时就让读者队列释放一个或多个读者,当写允许时,释放第一个写者操作。
读者优先:
如果没有写者正在操作,则读者不需要等待,用一个整型变量readcount记录当前的读者数目,用于确定是否释放写者线程,(当readcout=0时,说明所有的读者都已经读完,释放一个写者线程),每个读者开始读之前都要修改readcount,为了互斥的实现对readcount的修改,需要一个互斥对象Mutex来实现互斥。
另外,为了实现写-写互斥,需要一个临界区对象write,当写者发出写的请求时,必须先得到临界区对象的所有权。
通过这种方法,可以实现读写互斥,当readcount=1时,(即第一个读者的到来时,),读者线程也必须申请临界区对象的所有权.
当读者拥有临界区的所有权,写者都阻塞在临界区对象write上。
当写者拥有临界区对象所有权时,第一个判断完readcount==1后,其余的读者由于等待对readcount的判断,阻塞在Mutex上!
写者优先:
写者优先和读者优先有相同之处,不同的地方在:
一旦有一个写者到来时,应该尽快让写者进行写,如果有一个写者在等待,则新到的读者操作不能读操作,为此添加一个整型变量writecount,记录写者的数目,当writecount=0时才可以释放读者进行读操作!
为了实现对全局变量writecount的互斥访问,设置了一个互斥对象Mutex3。
为了实现写者优先,设置一个临界区对象read,当有写者在写或等待时,读者必须阻塞在临界区对象read上。
读者除了要一个全局变量readcount实现操作上的互斥外,还需要一个互斥对象对阻塞在read这一个过程实现互斥,这两个互斥对象分别为mutex1和mutex2。
//////////////////////////////////////
所用的API:
参数略(MSDN查看)//代码中有部分没有使用,但是可以在其他地方自己设计程序的时候使用。
1.CreateThread();
2.ExitThread();
3.Sleep();
4.CreateMutex();
5.ReleaseMutex();
6.WaitForSingleObject();
7.WaitForMutipleObjects();
8.CreateSemapore();
9.ReleaseSemapore();
10.InitializeCriticalSection();
11.EnterCriticalSection();
12.LeaveCriticalSection();
///////////////////////////////////
原代码文件名:
1.ReaderAndWriter.CPP//具体的实现
2.thread.dat//辅助的文件,但是必不可以少。
代码
一.ReaderAndWriter.CPP文件的具体内容:
//来自:
windows内核实验教程
//机械工业出版社
//ISBN:
7-111-10880-9/TP.2600
//制作者:
yuhejun@
//Formoreinformation:
//2005.11.9
//beijingchangping
//DebugVision
//Description:
这是一个关于操作系统内核实验的一段程序,读者和写者的问题的模拟实现.
//开发环境:
WINXP+VC6ConsoleApplication
#include"windows.h"
#include
#include
#include
#include
#include
#include
#defineREADER'R'//读者
#defineWRITER'W'//写者
#defineINTE_PER_SEC1000//每秒时钟中断的数目
#defineMAX_THREAD_NUM64//最大线程数
#defineMAX_FILE_NUM32//最大文件数目数
#defineMAX_STR_LEN32//字符串的长度
intreadcount=0;//读者数目
intwritecount=0;//写者数目
CRITICAL_SECTIONRP_Write;//临界资源
CRITICAL_SECTIONcs_Write;
CRITICAL_SECTIONcs_Read;
structThreadInfo
{
intserial;//线程序号
charentity;//线程类别(判断是读者还是写者线程)
doubledelay;//线程延迟时间
doublepersist;//线程读写操作时间
};
///////////////////////////////////////////////////////////////////////////
//读者优先---读者线程
//P:
读者线程信息
voidRP_ReaderThread(void*p)
{
//互斥变量
HANDLEh_Mutex;
h_Mutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_readcount");
DWORDwait_for_mutex;//等待互斥变量所有权
DWORDm_delay;//延迟时间
DWORDm_persist;//读文件持续时间
intm_serial;//线程序号