操作系统读者与写者问题课程设计报告[1].doc
《操作系统读者与写者问题课程设计报告[1].doc》由会员分享,可在线阅读,更多相关《操作系统读者与写者问题课程设计报告[1].doc(16页珍藏版)》请在冰豆网上搜索。
沈阳理工大学课程设计专用纸No1
课程设计任务书
学院
信息学院
专业
计算机科学与技术
学生姓名
学号
题目
读者与写者问题(进程同步问题)
内容及要求:
内容:
读者与写者问题(进程同步问题)
实验目的:
了解进程同步的概念,理解信号量机制的原理,掌握信号量解决同步问题的方法,进而学会进程的同步与互斥。
设计要求:
编程模拟教材中讨论读者与写者的问题,要求能显示结果。
任务交付:
1.程序源代码;
2课程设计论文及电子文档。
进度安排:
16周——确定题目,查找资料,上机编程;
20周——上机编程调试,验收答辩,提交课程序设计报告书。
指导教师(签字):
年月日
学院院长(签字):
年月日
目录
一、课程设计目的及要求 1
二、相关知识 1
三、题目分析 2
四、概要设计 4
五、代码及流程 5
六、运行结果 11
七、设计心得 12
八、参考文献 12
12
一、课程设计目的及要求
读者与写者问题(进程同步问题)
用n个线程来表示n个读者或写者。
每个线程按相应测试数据文件的要求,进行读写操作。
请用信号量机制分别实现读者优先和写者优先的读者-写者问题。
读者-写者问题的读写操作限制:
1)写-写互斥;
2)读-写互斥;
3)读-读允许;
写者优先的附加限制:
如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。
二、相关知识
WindowsAPI:
在本实验中涉及的API有:
1线程控制:
CreateThread完成线程创建,在调用进程的地址空间上创建一个线程,以执行指定的函数;它的返回值为所创建线程的句柄。
HANDLECreateThread(
LPSECURITY_ATTRIBUTESlpThreadAttributes, //SD
DWORDdwStackSize, //initialstacksize
LPTHREAD_START_ROUTINElpStartAddress, //thread
function
LPVOIDlpParameter, //threadargument
DWORDdwCreationFlags, //creationoption
LPDWORDlpThreadId //threadidentifier
);
2ExitThread用于结束当前线程。
VOIDExitThread(
DWORDdwExitCode //exitcodeforthisthread
);
3Sleep可在指定的时间内挂起当前线程。
VOIDSleep(
DWORDdwMilliseconds//sleeptime
);
4信号量控制:
WaitForSingleObject可在指定的时间内等待指定对象为可用状态;
DWORDWaitForSingleObject(
HANDLEhHandle, //handletoobject
DWORDdwMilliseconds //time-outinterval
);
hHandle为等待的对象,也就是实现同步或者互斥的对象。
该函数一执行,相应的信号量就减去1,如果信号量小于等于0,那么他一直在循环。
5实现信号量互斥和同步
CreateSemaphore用于创建信号量,根据参数的不同可以利用它实现互斥和同步。
ReleaseSemaphore用于释放信号量,使用后相应的信号量加1
HANDLECreateSemaphore(
LPSECURITY_ATTRIBUTESlpSemaphoreAttributes,//SD
LONG,lInitialCount, //initialcount
LONG,lMaximumCount, //maximumcount
LPCTSTRlpName //objectname
);
ReleaseSemaphore(
HANDLEhSemaphore, //handletosemaphore
LONGlRelseaseCount, //contincrementamount
LPLONGlpPreviousCount //previouscount
);
三、题目分析
将所有的读者和所有的写者分别放进两个等待队列中,当读允许时就让读者队列释放一个或多个读者,当写允许时,释放第一个写者操作。
(1)构筑读者进程和写者进程间的临界区
题目中说的一批数据被多个读者、写者共享使用,允许多个读者同时访问这些数据,但是如果有一个写者在访问数据时,就不允许其他读者或写者使用,所以,对这一批数据既要保证读者和写者互斥使用,也要保证写者与写者互斥使用。
也就是说,在读者进程程序中,使用数据的程序段应该构成临界区;在写者进程程序中,使用数据的程序段应该构成临界区。
(2)判定是否是第一个读者
根据上面的分析,希望在读者进程中有一个办法能判定请求进入临界区的是否是第一个读者。
如果是第一个读者,就对信号量wsem做P操作,以取得和写者的同步。
为此,设置一个变量rfirst,初值为0.任何一个读者运行时,都现在rfirst上加1,然后判定他是否取值为1.如果是1,则做P(wrt),否则不做。
(3)判定是否是第一个写者
原理同
(2)判定是否为第一个读者。
(4)写者优先问题的解决需要用到的如下的信号量和变量
rsem:
初值为1的互斥信号量,在至少有一个写者准备访问数据时就不允许随后来的读者访问数据
wserm:
初值为1的互斥信号量,之后有一个写者访问数据时其他写者和读者就被阻止对数据的访问
ReadMutex:
创建写者的互斥信号量,初值为1
WriteMutex:
创建读者的互斥信号量,初值为1
z:
初值为1的互斥信号量,在至少有一个写着准备访问数据、且后面已经来一个读者时再来的读者将在这个信号量上等待
rifrrst:
读者计数变量,初值为0
wfirst:
写者计数变量,初值为0
写者优先的PV原语:
reader(i):
{
P(z);
P(rsem);
P(ReadMutex);
rfirst=rfirst+1;
if(rfirst==1)
P(wsem);
V(ReadMutex);
V(rsem);
V(z);
读取所需数据;
P(ReadMutex);
rfirst=rfirst-1;
if(rfirst==0)
V(wsem);
V(ReadMutex);
}
Writer():
{
P(WriteMutex);
wfirst=wfirst+1;
if(wfirst==1)
P(rsem);
V(WritedMutex);
P(wsem);
改写所需数据;
V(wsem);
P(WriteMutex);
wfirst=wfirst-1;
if(wfirst==0)
V(rsem);
V(WriteMutex);
}
读者写者
图3.1读者-写者的完整流程框图
(5)读者优先
与写者优先算法相反,有一个读者优先的算法,即只要有读者在读数据,写者被拒绝在临界区外面,如果有源源不断的写者来,但是只要写者不是第一个,那么写者将会永远被拒绝在临界区外面。
wrt:
:
初值为1的互斥信号量,只要有一个写者访问数据,则其他写者和读者就要被阻止对数据的访问。
mutex:
保证读者互斥操作first的信号量,初值为1
first:
读者计数变量,初值为0
读者优先的PV原语:
write():
{
P(wrt);
对数据进行修改;
V(wrt);
}
read():
{
P(mutex);
first=first+1;
if(first==1)
P(wrt);
V(mutex);
读取所需数据
P(mutex);
first=first+1;
if(first==0)
V(wrt);
V(mutex);
}
四、概要设计
(1)控制流程
用CheckPersonList(PersonLists)函数检查PersonLists中是否有为创建的进程(读写者)。
如果有则创建相应的读写线程
(2)创建读写者
用boolCreateReader(intStartTime,intWorkTime)函数创建读者写者相应的线程,其中由windows提供的函数为CreateThread(NULL,0,ReaderProc,(LPVOID)pPerson,0,&dwThreadID);返回的是DWORD型变量。
在CreateReader(intStartTime,intWorkTime)中还会初始化相应的读写者的基本信息,例如何时申请数据何时读数据何时关闭线程等等。
(3)读写者进程
参见图2.1读者-写者的完整流程图。
(4)同步与互斥
WaitForSingleObject(信号量名字,infinite)和ReleaseSemaphore(信号量名字,1,null)用于实现同步于互斥,执行WaitForSingleObject(信号量名字,infinite)信号量相应的信号量减1,执行ReleaseSemaphore(信号量名字,1,null)恢复1。
五、代码及流程
//写者优先算法
#include
#include
#include
#include
#include
#include
#defineMAX_PERSON10
#defineREADER0
#defineWRITER1
#defineEND-1
#defineRREADER
#defineWWRITER
typedefstruct_Person
{
HANDLEThread;
intType;
intStartTime;
intWorkTime;
intID;
}Person;
PersonPersons[MAX_PERSON];
intNumPerson=0;
longCurrentTime=0;
intPersonLists[]={
1,R,1,3,
2,W,2,5,/*读写互斥*/
3,W,5,5,/*写写互斥*/
4,R,3,5,/*写读互斥*/
5,R,15,2,/*读读不互斥*/
END,
};
intrfirst=0;
intwfirst=0;
intNumOfReaders=0;
intNumOfWriters=0;
HANDLErsem;/*初值为1的互斥信号量,在至少有一个写者