读者写者实验报告.docx
- 文档编号:10380909
- 上传时间:2023-02-10
- 格式:DOCX
- 页数:16
- 大小:50.65KB
读者写者实验报告.docx
《读者写者实验报告.docx》由会员分享,可在线阅读,更多相关《读者写者实验报告.docx(16页珍藏版)》请在冰豆网上搜索。
读者写者实验报告
操作系统原理实验报告
实验名称:
操作系统
姓名:
XXX
学号:
xxxxxxxxxx
班级:
xxx
指导老师:
xxx
一、实验内容
在Windows2000环境下,创建一个控制台进程,此进程包含n个线程。
用这n个线程来表示n个读者或写者。
每个线程按相应测试数据文件(后面有介绍)的要求进行读写操作。
用信号量机制分别实现读者优先和写者优先的读者-写者问题。
读者-写者问题的读写操作限制(包括读者优先和写者优先):
1)写-写互斥,即不能有两个写者同时进行写操作。
2)读-写互斥,即不能同时有一个线程在读,而另一个线程在写。
,
3)读-读允许,即可以有一个或多个读者在读。
读者优先的附加限制:
如果一个读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。
写者优先的附加限制:
如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。
运行结果显示要求:
要求在每个线程创建、发出读写操作申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确定所有处理都遵守相应的读写操作限制。
二、实验目的
在Windows2000环境下,创建一个控制台进程,此进程包含n个线程。
用这n个线程来表示n个读者或写者。
每个线程按相应测试数据文件(后面有介绍)的要求进行读写操作。
用信号量机制分别实现读者优先和写者优先的读者-写者问题。
三、实验原理
1).读者优先
读者优先指的是除非有写者在写文件,否则读者不需要等待。
所以可以用一个整型变量read_count记录当前的读者数目,用于确定是否需要释放正在等待的写者线程(当read_count=O时,表明所有的读者读完,需要释放写者等待队列中的一个写者)。
每一个读者开始读文件时,必须修改read_count变量。
因此需要一个互斥对象mutex来实现对全局变量read_count修改时的互斥。
另外,为了实现写-写互斥,需要增加一个临界区对象write。
当写者发出写请求时,必须申请临界区对象的所有权。
通过这种方法,也可以实现读-写互斥,当read_count=l时(即第一个读者到来时),读者线程也必须申请临界区对象的所有权。
当读者拥有临界区的所有权时,写者阻塞在临界区对象write上。
当写者拥有临界区的所有权时,第一个读者判断完"read_count==1"后阻塞在write上,其余的读者由于等待对read_count的判断,阻塞在mutex上。
2).写者优先
写者优先与读者优先类似;不同之处在于一旦一个写者到来,它应该尽快对文件进行写操作,如果有一个写者在等待,则新到来的读者不允许进行读操作。
为此应当添加一个整型变量write_count,用于记录正在等待的写者的数目,当write_count=O时,才可以释放等待的读者线程队列。
为了对全局变量write_count实现互斥,必须增加一个互斥对象mutex3。
为了实现写者优先,应当添加一个临界区对象read,当有写者在写文件或等
待时,读者必须阻塞在read上。
·
读者线程除了要对全局变量read_count实现操作上的互斥外,还必须有一个互斥对象对阻塞,read这一过程实现互斥。
这两个互斥对象分别命名为mutex1和mutex2。
四、实验过程
在Windows2000环境下,创建一个控制台进程。
用VC++实现。
读者优先指的是除非有写者在写文件,否则读者不需要等待。
所以可以用一个整型变量read_count记录当前的读者数目,用于确定是否需要释放正在等待的写者线程(当read_count=O时,表明所有的读者读完,需要释放写者等待队列中的一个写者)。
每一个读者开始读文件时,必须修改read_count变量。
因此需要一个互斥对象mutex来实现对全局变量read_count修改时的互斥。
另外,为了实现写-写互斥,需要增加一个临界区对象write。
当写者发出写请求时,必须申请临界区对象的所有权。
通过这种方法,也可以实现读-写互斥,当read_count=l时(即第一个读者到来时),读者线程也必须申请临界区对象的所有权。
当读者拥有临界区的所有权时,写者阻塞在临界区对象write上。
当写者拥有临界区的所有权时,第一个读者判断完"read_count==1"后阻塞在write上,其余的读者由于等待对read_count的判断,阻塞在mutex上。
写者优先与读者优先类似;不同之处在于一旦一个写者到来,它应该尽快对文件进行写操作,如果有一个写者在等待,则新到来的读者不允许进行读操作。
为此应当添加一个整型变量write_count,用于记录正在等待的写者的数目,当write_count=O时,才可以释放等待的读者线程队列。
为了对全局变量write_count实现互斥,必须增加一个互斥对象mutex3。
为了实现写者优先,应当添加一个临界区对象read,当有写者在写文件或等
待时,读者必须阻塞在read上。
·
读者线程除了要对全局变量read_count实现操作上的互斥外,还必须有一个互斥对象对阻塞,read这一过程实现互斥。
这两个互斥对象分别命名为mutex1和mutex2。
结构:
头文件
定义全局变量
RP_ReaderThread()读者优先---读者线程
RP_WriterThread()读者优先---写者线程
ReaderPriority()读者优先处理函数
WP_ReaderThrea()写者优先---读者线程
WP_WriterThread()写者优先---写者线程
WriterPriority()写者优先处理函数
主函数:
包含对dat文件的读取以及函数的调用。
代码:
附录
五、实验结果
界面:
测试数据:
2W45
3R52
4R65
5W5.13
结果
读者优先
写者优先
六、实验心得体会
通过对读者写者问题的编程,对线程有了更深的了解,希望在后面的学习中懂得更多。
七、参考文献
老师提供的资料,以及互联网查阅。
八、附录
#include"windows.h"
#include
#include
#include
#include
#include
#include
#include"winbase.h"
#defineREADER'R'//读者
#defineWRITER'W'//写者
#defineINTE_PER_SEC1000//每秒时钟中断的数目
#defineMAX_THREAD_NUM64//最大线程数
intnReaderCnt=0;//读者计数
intnWriterCnt=0;//写者计数
HANDLEhWrite=:
:
CreateSemaphore(NULL,1,1,NULL);//写开始信号
HANDLEhRead=:
:
CreateSemaphore(NULL,1,1,NULL);//读开始信号
HANDLEhRCMutex=:
:
CreateMutex(NULL,FALSE,NULL);
HANDLEhWCMutex=:
:
CreateMutex(NULL,FALSE,NULL);
HANDLEhReadMutex=:
:
CreateMutex(NULL,FALSE,NULL);
//从测试数据文件中获取的线程信息
structThreadInfo
{
ThreadInfo()
{
nSerialNo=0;
cType='^';
dDelayTime=0.0;
dOpeTime=0.0;
}
intnSerialNo;//线程序号
charcType;//线程类别
doubledDelayTime;//线程延迟时间
doubledOpeTime;//线程读写操作时间
};
//读者优先---读者线程
//P:
读者线程信息
voidRP_ReaderThread(void*p)
{
intnSerialNo=((ThreadInfo*)(p))->nSerialNo;//从文件中读取线程序号
DWORDdwReadTime=(DWORD)(((ThreadInfo*)(p))->dOpeTime*INTE_PER_SEC);
DWORDdwDelay=(DWORD)(((ThreadInfo*)(p))->dDelayTime*INTE_PER_SEC);
Sleep(dwDelay);
printf("Readerthread%dsentsthereadingrequire.\n",nSerialNo);
WaitForSingleObject(hRCMutex,INFINITE);
nReaderCnt++;
if(nReaderCnt==1)
{
WaitForSingleObject(hWrite,INFINITE);
}
ReleaseMutex(hRCMutex);
printf("Readerthread%dbeginstoreadfile.\n",nSerialNo);
Sleep(dwReadTime);
printf("Readerthread%dfinishedreadingfile.\n",nSerialNo);
WaitForSingleObject(hRCMutex,INFINITE);
nReaderCnt--;
if(nReaderCnt==0)
{
ReleaseSemaphore(hWrite,1,NULL);
}
ReleaseMutex(hRCMutex);
}
//读者优先---写者线程
//P:
写者线程信息
voidRP_WriterThread(void*p)
{
intnSerialNo=((ThreadInfo*)(p))->nSerialNo;//从参数中获得信息
DWORDdwWriteTime=(DWORD)(((ThreadInfo*)(p))->dOpeTime*INTE_PER_SEC);
DWORDdwDelay=(DWORD)(((ThreadInfo*)(p))->dDelayTime*INTE_PER_SEC);
Sleep(dwDelay);
printf("Writethread%dsentsthewritingrequire.\n",nSerialNo);
WaitForSingleObject(hWrite,INFINITE);
printf("Writerthread%dbeginstowritetothefile.\n",nSerialNo);
Sleep(dwWriteTime);
printf("Writethread%dfinishedwritingtothefile.\n",nSerialNo);
ReleaseSemaphore(hWrite,1,NULL);
}
//读者优先处理函数
//file:
文件名
voidReaderPriority(char*file)
{
intnThreadCnt=0;
DWORDdwThreadID=0;
nReaderCnt=0;//初始化读写者计数
HANDLEhThreads[MAX_THREAD_NUM];
ThreadInfooThreadInfo[MAX_THREAD_NUM];
ifstreaminFile;
inFile.open(file);
printf("ReaderPriority:
\n\n");
while(inFile)
{
//读入每一个读者,写者的信息
inFile>>oThreadInfo[nThreadCnt].nSerialNo;
inFile>>oThreadInfo[nThreadCnt].cType;
inFile>>oThreadInfo[nThreadCnt].dDelayTime;
inFile>>oThreadInfo[nThreadCnt].dOpeTime;
if('^'!
=oThreadInfo[nThreadCnt].cType)
{
nThreadCnt++;
}
inFile.get();
}
//创建线程
for(inti=0;i { if((oThreadInfo[i].cType==READER)||(oThreadInfo[i].cType=='r')) { hThreads[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_ReaderThread),//创建读者进程 &oThreadInfo[i],CREATE_SUSPENDED,&dwThreadID); } else { hThreads[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_WriterThread),//创建写线程 &oThreadInfo[i],CREATE_SUSPENDED,&dwThreadID); } } for(i=0;i { ResumeThread(hThreads[i]); } WaitForMultipleObjects(nThreadCnt,hThreads,TRUE,INFINITE); printf("Allreaderandwriterhavefinishedoperating.\n"); } //写者优先---读者线程 //P: 读者线程信息 voidWP_ReaderThread(void*p) { intnSerialNo=((ThreadInfo*)(p))->nSerialNo;//从参数中得到信息 DWORDdwReadTime=(DWORD)(((ThreadInfo*)(p))->dOpeTime*INTE_PER_SEC); DWORDdwDelay=(DWORD)(((ThreadInfo*)(p))->dDelayTime*INTE_PER_SEC); Sleep(dwDelay); printf("Readerthread%dsentsthereadingrequire.\n",nSerialNo); WaitForSingleObject(hReadMutex,INFINITE); WaitForSingleObject(hRead,INFINITE); WaitForSingleObject(hRCMutex,INFINITE); nReaderCnt++; if(nReaderCnt==1) { WaitForSingleObject(hWrite,INFINITE); } ReleaseMutex(hRCMutex); ReleaseSemaphore(hRead,1,NULL); ReleaseMutex(hReadMutex); printf("Readerthread%dbeginstoreadfile.\n",nSerialNo); Sleep(dwReadTime); printf("Readerthread%dfinishedreadingfile.\n",nSerialNo); WaitForSingleObject(hRCMutex,INFINITE); nReaderCnt--; if(nReaderCnt==0) { ReleaseSemaphore(hWrite,1,NULL); } ReleaseMutex(hRCMutex); } //写者优先---写者线程 //P: 写者线程信息 voidWP_WriterThread(void*p) { intnSerialNo=((ThreadInfo*)(p))->nSerialNo; DWORDdwWriteTime=(DWORD)(((ThreadInfo*)(p))->dOpeTime*INTE_PER_SEC); DWORDdwDelay=(DWORD)(((ThreadInfo*)(p))->dDelayTime*INTE_PER_SEC); Sleep(dwDelay); printf("Writerthread%dsentsthewritingrequire.\n",nSerialNo); WaitForSingleObject(hWCMutex,INFINITE); nWriterCnt++; if(nWriterCnt==1) { WaitForSingleObject(hRead,INFINITE); } ReleaseMutex(hWCMutex); WaitForSingleObject(hWrite,INFINITE); printf("Writerthread%dbeginstowritetothefile.\n",nSerialNo); Sleep(dwWriteTime); printf("Writerthread%dfinishedwritingtothefile.\n",nSerialNo); ReleaseSemaphore(hWrite,1,NULL); WaitForSingleObject(hWCMutex,INFINITE); nWriterCnt--; if(nWriterCnt==0) { ReleaseSemaphore(hRead,1,NULL); } ReleaseMutex(hWCMutex); } //写者优先处理函数 //file: 文件名 voidWriterPriority(char*file) { intnThreadCnt=0; DWORDdwThreadID; HANDLEhThreads[MAX_THREAD_NUM]; ThreadInfooThreadInfo[MAX_THREAD_NUM]; nReaderCnt=0; nWriterCnt=0; ifstreaminFile; inFile.open(file); printf("Writerpriority: \n\n"); while(inFile) { inFile>>oThreadInfo[nThreadCnt].nSerialNo; inFile>>oThreadInfo[nThreadCnt].cType; inFile>>oThreadInfo[nThreadCnt].dDelayTime; inFile>>oThreadInfo[nThreadCnt].dOpeTime; if('^'! =oThreadInfo[nThreadCnt].cType) { nThreadCnt++; } inFile.get(); } for(inti=0;i { if((oThreadInfo[i].cType==READER)||(oThreadInfo[i].cType=='r')) { hThreads[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(WP_ReaderThread),//创建读者进程 &oThreadInfo[i],CREATE_SUSPENDED,&dwThreadID); } else { hThreads[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(WP_WriterThread), &oThreadInfo[i],CREATE_SUSPENDED,&dwThreadID); } } for(i=0;i { ResumeThread(hThreads[i]); } WaitForMultipleObjects(nThreadCnt,hThreads,TRUE,INFINITE); printf("Allreaderandwriterhavefinishedoperating.\n"); } intmain(intargc,char*argv[]) { charch; while(true) { printf("*************************************\n"); printf("1.ReaderPriority\n"); printf("2.WriterPriority\n"); printf("3.ExittoWindows\n"); printf("*************************************\n"); printf("Enteryourchoice1,2,3: "); do{ ch=(char)_getch(); }while(ch! ='1'&&ch! ='2'&&ch! ='3'); system("cls"); if(ch=='3') return0; elseif(ch=='1') ReaderPriority("thread.dat"); else WriterPriority("thread.dat"); printf("\nPressAnyKeytoCoutinue: "); _getch(); system("cls"); } return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 读者 实验 报告