读者与写者问题.docx
《读者与写者问题.docx》由会员分享,可在线阅读,更多相关《读者与写者问题.docx(11页珍藏版)》请在冰豆网上搜索。
读者与写者问题
2012--2013学年第一学期学院综合设计《读者与写者问题》
学号:
姓名:
成绩:
评语:
设计要求:
用P、V操作实现读者写者问题,写者不多于5个,读者不多于20个。
所有读者和写者访问同一个文件all.txt,每个写者向文件添加一行,内容是“I'mthewriternumberX.ItisTIME.”,其中X是pid,TIME是访问文件的时间,格式为hh-mm-ss.ddd;每个读者读出最后一个写者的pid和写的时间,并在屏幕上输出。
每个读者或写者的访问次数为32-100之间的随机数,同一个写者相邻两次的访问间隔不得短于0.1秒,同一个读者相邻两次的访问间隔不得短于0.05秒。
读者写者问题的实现
1、概述
1.1设计题目
读者写者问题的实现
1.2设计目的
通过对操作系统内核实现代码的阅读、修改、设计,理解和掌握复杂的操作系统的工作原理。
通过研究Linux的线程机制和信号量实现读者写者(Reader-Writer)问题并发控制。
1.3开发环境
使用的操作系统:
Linux系统
使用的编程语言:
C语言
1.4设计要求
用P、V操作实现读者写者问题,写者不多于5个,读者不多于20个。
所有读者和写者访问同一个文件all.txt,每个写者向文件添加一行,内容是“I'mthewriternumberX.ItisTIME.”,其中X是pid,TIME是访问文件的时间,格式为hh-mm-ss.ddd;每个读者读出最后一个写者的pid和写的时间,并在屏幕上输出。
每个读者或写者的访问次数为32-100之间的随机数,同一个写者相邻两次的访问间隔不得短于0.1秒,同一个读者相邻两次的访问间隔不得短于0.05秒。
2、设计思想
读者写者问题的定义如下:
有一个许多进程共享的数据区,这个数据区可以是一个文件或者主存的一块空间;有一些只读取这个数据区的进程(Reader)和一些只往数据区写数据的进程(Writer),此外还需要满足以下条件:
(1)任意多个读进程可以同时读这个文件;
(2)一次只有一个写进程可以往文件中写;(3)如果一个写进程正在进行操作,禁止任何读进程度文件。
3、具体程序实现
#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,W,4,5,
2,W,16,4,
3,R,5,2,
4,W,6,5,
5,R,4,3,
END,
};
intg_NumOfReading=0;
intg_NumOfWriteRequest=0;//申请写进程的个数
HANDLEg_hReadSemaphore;//读者信号
HANDLEg_hWriteSemaphore;//写者信号
boolfinished=false;//所有的读完成
//boolwfinished=false;//所有的写完成
voidCreatePersonList(int*pPersonList);
boolCreateReader(intStartTime,intWorkTime,intID);
boolCreateWriter(intStartTime,intWorkTime,intID);
DWORDWINAPIReaderProc(LPVOIDlpParam);
DWORDWINAPIWriterProc(LPVOIDlpParam);
intmain()
{
g_hReadSemaphore=CreateSemaphore(NULL,1,100,NULL);//创建信号灯,当前可的资源数为,最大为
g_hWriteSemaphore=CreateSemaphore(NULL,1,100,NULL);//创建信号灯,当前可用的资源数为,最大为
CreatePersonList(g_PersonLists);//CreateAllthereaderandwriters
printf("Createdallthereaderandwriter\n...\n");
g_CurrentTime=0;
while(true)
{
g_CurrentTime++;
Sleep(300);//300ms
printf("CurrentTime=%d\n",g_CurrentTime);
if(finished)return0;
system("pause");
}//return0;
}
voidCreatePersonList(int*pPersonLists)
{
inti=0;
int*pList=pPersonLists;
boolRet;
while(pList[0]!
=END)
{
switch(pList[1])
{
caseR:
Ret=CreateReader(pList[2],pList[3],pList[0]);//351,w452,523,654
break;
caseW:
Ret=CreateWriter(pList[2],pList[3],pList[0]);
break;
}
if(!
Ret)
printf("CreatePerson%diswrong\n",pList[0]);
pList+=4;//movetonextpersonlist
}
}
DWORDWINAPIReaderProc(LPVOIDlpParam)//读过程
{
Person*pPerson=(Person*)lpParam;
//waitforthestarttime
while(g_CurrentTime!
=pPerson->m_nStartTime)
{}
printf("Reader%disRequesting...\n",pPerson->m_nID);
printf("\n\n************************************************\n");
//waitforthewriterequest
WaitForSingleObject(g_hReadSemaphore,INFINITE);
if(g_NumOfReading==0)
{
WaitForSingleObject(g_hWriteSemaphore,INFINITE);
}
g_NumOfReading++;
ReleaseSemaphore(g_hReadSemaphore,1,NULL);
pPerson->m_nStartTime=g_CurrentTime;
printf("Reader%disReadingtheSharedBuffer...\n",pPerson->m_nID);
printf("\n\n************************************************\n");
while(g_CurrentTime<=pPerson->m_nStartTime+pPerson->m_nWorkTime)
{}
printf("Reader%disExit...\n",pPerson->m_nID);
printf("\n\n************************************************\n");
WaitForSingleObject(g_hReadSemaphore,INFINITE);
g_NumOfReading--;
if(g_NumOfReading==0)
{
ReleaseSemaphore(g_hWriteSemaphore,1,NULL);//此时没有读者,可以写
}
ReleaseSemaphore(g_hReadSemaphore,1,NULL);
if(pPerson->m_nID==4)finished=true;//所有的读写完成
ExitThread(0);
return0;
}
DWORDWINAPIWriterProc(LPVOIDlpParam)
{
Person*pPerson=(Person*)lpParam;
//waitforthestarttime
while(g_CurrentTime!
=pPerson->m_nStartTime)
{}
printf("Writer%disRequesting...\n",pPerson->m_nID);
printf("\n\n************************************************\n");
WaitForSingleObject(g_hWriteSemaphore,INFINITE);
//modifythewriter'srealstarttime
pPerson->m_nStartTime=g_CurrentTime;
printf("Writer%disWrittingtheSharedBuffer...\n",pPerson->m_nID);
while(g_CurrentTime<=pPerson->m_nStartTime+pPerson->m_nWorkTime)
{}
printf("Writer%disExit...\n",pPerson->m_nID);
printf("\n\n************************************************\n");
//g_NumOfWriteRequest--;
ReleaseSemaphore(g_hWriteSemaphore,1,NULL);
if(pPerson->m_nID==4)finished=true;//所有的读写完成
ExitThread(0);
return0;
}
boolCreateReader(intStartTime,intWorkTime,intID)
{
DWORDdwThreadID;
if(g_NumPerson>=MAX_PERSON)
returnfalse;
Person*pPerson=&g_Persons[g_NumPerson];
pPerson->m_nID=ID;
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,intID)
{
DWORDdwThreadID;
if(g_NumPerson>=MAX_PERSON)
returnfalse;
Person*pPerson=&g_Persons[g_NumPerson];
pPerson->m_nID=ID;
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;
}
4、运行结果
测试数据文件包括n行测试数据,分别描述创建的n个线程是读者还是写者,以及读写操作的开始时间和持续时间。
每行测试数据包括四个字段,各字段间用空格分隔。
第一字段为一个正整数,表示线程序号。
第二字段表示相应线程角色,R表示读者是,W表示写者。
第三字段为一个正数,表示读写操作的开始时间。
线程创建后,延时相应时间(单位为秒)后发出对共享资源的读写申请。
第四字段为一个正数,表示读写操作的持续时间。
当线程读写申请成功后,开始对共享资源的读写操作,该操作持续相应时间后结束,并释放共享资源。
下面是一个测试数据文件的例子:
1,W,4,5,2,W,16,4,3,R,5,2,4,W,6,5,5,R,4,3,
在读者写者同时在队列中等待申请资时,读者优先调用资源。
而且如果一个读者申请进行读操作时已有另一读者正在进行读操作,则该读者可直接开始读操作,即读读允许。
5、总结
通过本次实验“读者-写者问题的实现”的学习对线程及其同步机制有了进一步的学习和掌握,并认识到同步可以保证在一个时间内只有一个线程对某个资源有控制权。
也使我对于linux有了全面的接触和了解,而linux所开放的源码的确为学计算机的人提供了很好的平台。
对程序设计思想也有了系统的设计的构想,为今后的程序设计奠定了基础。
总体而言,这次通过“读者-写者问题”这一经典的线程同步问题,对读者写者问题的编写让我对同步机构应用有了深入的了解,懂得了运用信号量实现进程间的互斥,也学会了如何实现不让共享资源同时修改。
本次试验也使我对C语言有了一个很好的复习和学习,对线程的创建及同步问题及其同步对象都有了很好的理解。
并能初步进行简单的程序编程,对程序的调式过程也使我更好了解到线程同步的具体运行过程,我也能够更好的理解程序。
学习语言是一个漫长的过程,我想只有在不断的实践练习中,才能更好的掌握编程的技巧,提高自己的编程能力,此次实验让我深深体会到自己还有很多东西需要学习。
6、参考文献
[1]《操作系统原理(第三版)》主编:
张尧学出版社:
清华大学出版社
[2]《操作系统实验教程》主编:
张丽芬,刘利雄出版社:
清华大学出版社
[3]《操作系统教程》主编:
孙钟秀出版社:
高等教育出版社