实验二 读者写者问题实验报告..

合集下载

读者写者实验报告

读者写者实验报告

读者写者实验报告
读者写者问题是指一个共享固定大小缓冲区的进程间通信问题,其中固定大小的缓冲区被多个读者进程和写者进程所共享。

读者进程从缓冲区中读取数据,而写者进程将数据写入缓冲区。

本实验目的是通过使用互斥锁、条件变量和信号量等同步机制,构建一个读者写者问题的解决方案。

实验环境:
- 操作系统:Linux
-编程语言:C语言
实验步骤:
1.创建共享内存缓冲区,用于读者和写者的数据传递。

2.创建互斥锁,用于保护共享内存缓冲区的访问。

3.创建条件变量,用于读者和写者之间的协调。

4.创建读者进程和写者进程,模拟读者写者的并发操作。

5.在读者进程中,通过互斥锁保护共享内存缓冲区,读取数据,并更新计数器。

6.在写者进程中,通过互斥锁保护共享内存缓冲区,写入数据,并更新计数器。

7.使用条件变量实现读者优先或写者优先的策略。

实验结果:
通过实验,我成功实现了读者写者问题的解决方案。

使用互斥锁可以保护共享资源的访问,防止读者和写者同时访问。

使用条件变量可以实现读者优先或写者优先的策略。

实验总结:
通过本次实验,我深入了解了读者写者问题,并且掌握了使用互斥锁、条件变量和信号量等同步机制来解决读者写者问题的方法。

在实现过程中,我遇到了一些困难,例如死锁和竞争条件等问题。


过调试和改进代码,我成功解决了这些问题,提高了程序的稳定性和性能。

在以后的工作中,我会更加注重并发编程的实践,提高自己解决问题
的能力。

北理工操作系统实验二读者写者问题

北理工操作系统实验二读者写者问题

本科实验报告实验名称:操作系统原理实验(读者写者问题)课程名称:操作系统原理实验时间:2015.10.30 任课教师:王耀威实验地点:10#102实验教师:苏京霞实验类型: 原理验证□综合设计□自主创新学生姓名:孙嘉明学号/班级:1120121474/05611202 组号:学院:信息与电子学院同组搭档:专业:信息对抗技术成绩:实验二:读者写者问题一、实验目的1.通过编写和调试程序以加深对进程、线程管理方案的理解;2.熟悉Windows多线程程序设计方法;二、实验要求在Windows环境下,创建一个控制台进程,此进程包含n个线程。

用这n个线程来表示n个读者或写者。

每个线程按相应测试数据文件(后面介绍)的要求进行读写操作。

用信号量机制分别实现读者优先和写者优先问题。

读者-写者问题的读写操作限制(包括读者优先和写者优先)1)写-写互斥:不能有两个写者同时进行写操作2)读-写互斥:不能同时有一个线程在读,而另一个线程在写。

3)读-读允许:可以有一个或多个读者在读。

读者优先的附加限制:如果读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。

运行结果显示要求:要求在每个线程创建、发出读写申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确定所有处理都遵守相应的读写操作限制。

测试数据文件包括 n行测试数据,分别描述创建的n个线程是读者还是写者,以及读写操作的开始时间和持续时间。

每行测试数据包括四个字段,每个字段间用空格分隔。

第1个字段为正整数,表示线程的序号。

第2个字段表示线程的角色,R表示读者,W表示写者。

第3个字段为一个正数,表示读写开始时间:线程创建后,延迟相应时间(单位为秒)后发出对共享资源的读写申请。

第4个字段为一个正数,表示读写操作的延迟时间。

当线程读写申请成功后,开始对共享资源进行读写操作,该操作持续相应时间后结束,释放该资源。

下面是一个测试数据文件的例子(在记事本手工录入数据):1 R 3 52 W 4 53 R 5 24 R 6 55 W 5.1 3三、实验环境硬件设备:个人计算机。

进程同步模拟设计——读者和写者问题

进程同步模拟设计——读者和写者问题

附件1:学号:012081034课程设计进程同步模拟设计——读者和题目写者问题学院计算机科学与技术学院专业计算机科学与技术班级计算机科学与技术姓名指导教师2011 年 1 月19 日目录目录 (1)1 设计概述 (4)1.1问题描述: (4)1.1.1规则: (4)1.1.2读者和写者的相互关系: (4)1.2采用信号量机制 (4)1.3 C++语言程序模拟用信号量机制实现生产者和消费者问题 (5)2课程设计目的及功能 (5)2.1 设计目的 (5)2.2 设计功能: (5)3 需求分析,数据结构或模块说明(功能与框图) (5)3.1数据结构 (5)3.2模块说明 (6)3.3开发平台及源程序的主要部分 (6)3.3.1写操作的设计: (6)3.3.2读操作的设计: (7)3.3.3主函数的设计: (9)3.4 功能流程图 (12)4测试用例,运行结果与运行情况分析 (12)4.1测试用例 (12)4.2运行结果 (13)4.3运行情况分析 (14)5自我评价与总结 (15)6 参考文献 (16)课程设计任务书学生姓名:专业班级:计算机科学与技术指导教师:工作单位:计算机科学与技术学院题目: 进程同步模拟设计——读者和写者问题初始条件:1.预备内容:阅读操作系统的进程管理章节内容,对进程的同步和互斥,以及信号量机制度有深入的理解。

2.实践准备:掌握一种计算机高级语言的使用。

要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.模拟用信号量机制实现读者和写者问题。

2.设计报告内容应说明:⑴课程设计目的与功能;⑵需求分析,数据结构或模块说明(功能与框图);⑶源程序的主要部分;⑷测试用例,运行结果与运行情况分析;⑸自我评价与总结:i)你认为你完成的设计哪些地方做得比较好或比较出色;ii)什么地方做得不太好,以后如何改正;iii)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);iv)完成本题是否有其他的其他方法(如果有,简要说明该方法);v)对实验题的评价和改进意见,请你推荐设计题目。

操作系统实验-读者写者问题

操作系统实验-读者写者问题

《计算机操作系统》实验报告题目读者写者问题学院(部)信息学院专业计算机科学与技术班级、学生姓名学号指导教师(签字)一、《二、问题描述一个数据文件或者记录,可以被多个进程共享,我们把只要求读该文件的进程称为“Reader进程”,其他进程则称为“Writer进程”。

允许多个进程同时读一个共享对象,因为读操作不会是数据文件混乱。

但不允许一个Writer进程和其他Reader进程或者Writer进程同时访问共享对象,因为这种访问将会引起混乱。

所谓“读者——写着问题(Reader—Writer Problem)”是指保证一个Writer进程必须与其他进程互斥地访问共享对象的同步问题三、解决问题为实现Reader与Writer进程间在读或写是的互斥而设置了一个互斥的信号量Wmutex。

另外,在设置一个整型变量Readcount表示正在读的进程数目。

由于只要有一个Reader进程在读,便不允许Writer去写。

因此,仅当Readercount=0时,表示尚无Reader进程在读时,Reader进程才需要进行Wait(wmutex)操作。

若Wait(Wmutex)操作成功,Reader 进程便可去读,相应地,做Readcount+1操作。

同理,仅当Reader进程在执行了Readercount-1操作后其值为0时,才执行Signal(Wmutex)操作,以便让Writer进程写。

又因为Readercount是一个可被多个Reader 进程访问的临界资源,因此也应该为它设置一个互斥信号量rmutex。

四、代码实现1、读者优先#include<iostream>#include<>using namespace std;CRITICAL_SECTION rmutex,wmutex;int wr;$int readernum;DWORD WINAPI reader(LPVOID IpParamter){cout<<"读者申请\n";wr++;EnterCriticalSection(&rmutex);if(readernum==0)EnterCriticalSection(&wmutex);readernum++;cout<<"读者进入成功正在读取\n";LeaveCriticalSection(&rmutex);Sleep(2000);—EnterCriticalSection(&rmutex);readernum--;cout<<"读者退出\n";wr--;if(readernum==0)LeaveCriticalSection(&wmutex);LeaveCriticalSection(&rmutex);return 0;}DWORD WINAPI writer(LPVOID PM){cout<<"写者申请\n";&while(wr!=0){}EnterCriticalSection(&wmutex);cout<<"写者已进入正在写入\n";Sleep(500);cout<<"写者退出\n";LeaveCriticalSection(&wmutex);return 0;}int main(){readernum=0;#wr=0;InitializeCriticalSection(&rmutex);InitializeCriticalSection(&wmutex);HANDLE hr[5];//定义读者线程HANDLE hw[5];//定义写者线程//int thnum;int drn=0; //输入的读者个数int dwn=0; //输入的写者个数cout<<"输入读者写者线程 1代表读者 2代表写者 0代表结束"<<endl;int th[10];int num=0;^cin>>th[num];while(th[num]){if(th[num]==1){drn++;}if(th[num]==2){dwn++;}num++;cin>>th[num];}&int hr1=0,hw1=0;for(int j=0;j!=num;j++){if(th[j]==1){hr[hr1]=CreateThread(NULL,0,reader,NULL,0,NULL);hr1++;}if(th[j]==2){hw[hw1]=CreateThread(NULL,0,writer,NULL,0,NULL);hw1++;}}>WaitForMultipleObjects(drn, hr, TRUE, INFINITE);WaitForMultipleObjects(dwn, hw, TRUE, INFINITE);for(int i=0;i!=drn;i++){CloseHandle(hr[i]);}for(int i=0;i!=dwn;i++){CloseHandle(hw[i]);}DeleteCriticalSection(&rmutex);DeleteCriticalSection(&wmutex);return 0;(}2、写者优先#include<iostream>#include<>using namespace std;CRITICAL_SECTION rmutex,wmutex;int ww;int readernum;DWORD WINAPI reader(LPVOID IpParamter){cout<<"读者申请\n";!while(ww!=0){}EnterCriticalSection(&rmutex);if(readernum==0){EnterCriticalSection(&wmutex);}cout<<"读者进入成功正在读取\n";readernum++;LeaveCriticalSection(&rmutex);Sleep(2000);EnterCriticalSection(&rmutex);-readernum--;if(readernum==0)LeaveCriticalSection(&wmutex);cout<<"读者退出\n";LeaveCriticalSection(&rmutex);return 0;}DWORD WINAPI writer(LPVOID PM){ww++;cout<<"写者申请\n";EnterCriticalSection(&wmutex);{cout<<"写者已进入正在写入\n";Sleep(1000);cout<<"写者退出\n";ww--;LeaveCriticalSection(&wmutex);return 0;}int main(){readernum=0;ww=0;InitializeCriticalSection(&rmutex);|InitializeCriticalSection(&wmutex);HANDLE hr[5];//定义读者线程HANDLE hw[5];//定义写者线程int drn=0; //输入的读者个数int dwn=0; //输入的写者个数cout<<"输入读者写者线程 1代表读者 2代表写者 0代表结束"<<endl;int th[10];int num=0;cin>>th[num];while(th[num]){if(th[num]==1){、drn++;}if(th[num]==2){dwn++;}num++;cin>>th[num];}int hr1=0,hw1=0;for(int j=0;j!=num;j++){if(th[j]==1){》hr[hr1]=CreateThread(NULL,0,reader,NULL,0,NULL);Sleep(10);hr1++;}if(th[j]==2){hw[hw1]=CreateThread(NULL,0,writer,NULL,0,NULL);Sleep(10);hw1++;}}WaitForMultipleObjects(drn, hr, TRUE, INFINITE);*WaitForMultipleObjects(dwn, hw, TRUE, INFINITE);for(int i=0;i!=drn;i++){CloseHandle(hr[i]);}for(int i=0;i!=dwn;i++){CloseHandle(hw[i]);}DeleteCriticalSection(&rmutex);DeleteCriticalSection(&wmutex);return 0;}3、执行结果读者优先在读者优先中先两个读者申请,再一个写者申请,再有两个读者申请。

读者写者问题实验报告

读者写者问题实验报告

读者写者问题实验报告1. 引言读者写者问题是操作系统中的经典同步问题,用于研究多线程环境下对共享资源的访问和保护。

在该问题中,有多个读者和写者同时对一个共享资源进行操作,需要保证并发访问时的正确性和效率。

通过本实验,我们将探讨读者写者问题的解决方案,并比较不同算法的性能差异。

2. 实验目标本实验的主要目标是通过实现和比较不同的读者写者问题算法,深入了解并发访问的挑战和解决方案。

具体而言,我们将研究以下几个方面:•设计并实现读者写者问题的解决方案•比较不同算法的性能差异•分析可能的优化策略3. 实验方法我们将使用Python编程语言来实现读者写者问题的解决方案。

在实验过程中,我们将尝试以下几种常见的算法:3.1. 读者优先算法在读者优先算法中,当有读者在访问共享资源时,其他读者可以同时访问,但写者需要等待。

只有当所有读者完成访问后,写者才能获得访问权限。

3.2. 写者优先算法在写者优先算法中,当有写者在访问共享资源时,其他读者和写者都需要等待。

只有当写者完成访问后,其他读者或写者才能获得访问权限。

3.3. 公平算法在公平算法中,读者和写者的访问权限是公平的,先到先得。

无论读者还是写者,都需要按照到达的顺序依次获取访问权限。

4. 实验步骤下面是我们实施实验的具体步骤:4.1. 实现基本的读者写者问题解决方案我们首先实现基本的读者写者问题解决方案,包括读者和写者的线程逻辑和共享资源的访问控制。

我们将使用互斥锁和条件变量来保证并发访问的正确性。

4.2. 实现读者优先算法在已有的基本解决方案的基础上,我们实现读者优先算法。

我们将通过优化访问控制的逻辑来实现读者优先的特性。

4.3. 实现写者优先算法类似地,我们在基本解决方案的基础上实现写者优先算法。

我们将调整访问控制的逻辑,使得写者优先于其他读者和写者。

4.4. 实现公平算法最后,我们实现公平算法。

我们将结合队列和条件变量等技术来确保读者和写者的访问顺序是公平的。

读者-写者问题说明书

读者-写者问题说明书

《操作系统原理》课程设计任务书题目:读者-写者问题的实现学生姓名:李志旭学号:13740113 班级:_13级软件工程_题目类型:软件工程(R)指导教师:陈文娟、马生菊一、设计目的学生通过该题目的设计过程,掌握读者、写者问题的原理、软件开发方法并提高解决实际问题的能力。

二、设计任务编写程序实现读者优先和写者优先问题:读者-写者问题的读写操作限制(包括读者优先和写者优先)写-写互斥:不能有两个写者同时进行写操作读-写互斥:不能同时有一个线程在读,而另一个线程在写。

读-读允许:可以有一个或多个读者在读。

三、设计要求1.分析设计要求,给出解决方案(要说明设计实现所用的原理、采用的数据结构)。

2.设计合适的测试用例,对得到的运行结果要有分析。

3.设计中遇到的问题,设计的心得体会。

4.文档:课程设计打印文档每个学生一份,并装在统一的资料袋中,资料袋前面要贴有学校统一的资料袋封面。

四、提交的成果1. 课程设计说明书内容包括(1) 封面(学院统一印制);(2) 课程设计任务书;(3) 中文摘要150字;关键词3-5个;(4) 目录;(5) 正文;(设计思想;各模块的伪码算法;函数的调用关系图;测试结果等)(6) 设计总结;(7) 参考文献;(8) 致谢等。

注:每一部分是单独的一章,要另起一页写。

2. 排版要求(1) 所有一级标题为宋体三号加粗(即上面写的2~8部分,单独一行,居中)(2) 所有二级标题为宋体四号加粗(左对齐)(3) 所有三级标题为宋体小四加粗(左对齐)(4) 除标题外所有正文为宋体小四,行间距为固定值22磅,每个段落首行缩进2字符(5) 目录只显示3级标题,目录的最后一项是无序号的“参考文献资料”。

3. 其他要求(班长负责,务必按照以下方式建文件夹)(1) 以班级为单位刻录光盘一张,光盘以班级命名,例如:“10级计算机科学与技术1班”;(2) 光盘内每人一个文件夹,以学号姓名命名——如“10730101 陈映霞”,内容包括任务书、设计文档。

实验二实验报告

实验二实验报告

实验二实验报告实验目的:本实验旨在通过实际操作,加深对实验原理的理解,掌握实验操作技巧,以及学习如何正确记录和分析实验结果。

实验仪器与材料:1. XXX型实验仪器2. XXX材料13. XXX材料24. XXX试剂5. 实验记录表格实验步骤:1. 材料准备在实验前,首先需要准备好所需的材料和试剂。

确保所有材料和试剂的质量和数量均符合实验要求。

2. 实验操作2.1 步骤一:XXX操作根据实验原理,操作XXX设备,将材料1与材料2进行混合,并设置相应的条件和参数。

注意在操作过程中保持安全和环境卫生。

2.2 步骤二:XXX操作根据实验原理,进行XXX操作,如加热、冷却、搅拌等,以促使反应发生,并观察反应情况。

2.3 步骤三:XXX操作根据实验原理,对实验结果进行采集和记录。

注意准确记录所用的仪器、试剂、操作条件等信息。

3. 数据处理与分析根据实验记录表格中的数据,进行数据处理和分析。

计算相关的实验参数,并绘制相应的图表和曲线。

对实验结果进行解读和讨论,提出可能的误差来源,并进行系统误差和随机误差的分析。

4. 实验结论经过实验数据的分析和讨论,得出以下结论:(1)总结实验结果的主要发现和规律。

(2)分析实验结果与预期目标之间的差异,并给出可能的原因和解释。

(3)对实验中存在的问题和改进的方向提出建议。

5. 实验总结通过本次实验,我深入理解了实验原理,并掌握了实验操作技巧。

同时,我也学会了如何正确记录和分析实验结果。

实验过程中的困难和挑战,让我更好地理解了科学研究的严谨性和耐心性。

通过对实验结果的评估和讨论,我可以应用所学的知识和技能,为将来的实验工作提供参考和改进方向。

6. 参考文献[1] 作者1. 文章标题1. 期刊名称,年份,卷号(期号):起止页码。

[2] 作者2. 文章标题2. 期刊名称,年份,卷号(期号):起止页码。

...以上实验报告按照一般实验报告的格式进行编写,旨在使读者能迅速了解实验目的、步骤、结果和结论。

读者写者问题

读者写者问题
2)读-写互斥,即不能同时有一个读者在读,同时却有一个写者在写
3)读读允许,即可以有2个以上的读者同时读
将所有的读者与所有的写者分别放进两个等待队列中,当读允许时就让读者队列释放一个或多个读者,当写允许时,释放第一个写者操作。读者写者问题的定义如下:有一个许多进程共享的数据区,这个数据区可以就是一个文件或者主存的一块空间;有一些只读取这个数据区的进程(Reader)与一些只往数据区写数据的进程(Writer),此外还需要满足以下条件:1)任意多个读进程可以同时读这个文件;2)一次只有一个写进程可以往文件中写;3)如果一个写进程正在进行操作,禁止任何读进程度文件。我们需要分两种情况实现该问题:
一设计概述
所谓读者写者问题,就是指保证一个writer进程必须与其她进程互斥地访问共享对象的同步问题。
读者写者问题可以这样的描述,有一群写者与一群读者,写者在写同一本书,读者也在读这本书,多个读者可以同时读这本书,但就是,只能有一个写者在写书,并且,读者必写者优先,也就就是说,读者与写者同时提出请求时,读者优先。当读者提出请求时需要有一个互斥操作,另外,需要有一个信号量S来当前就是否可操作。
信号量机制就是支持多道程序的并发操作系统设计中解决资源共享时进程间的同步与互斥的重要机制,而读者写者问题则就是这一机制的一个经典范例。
与记录型信号量解决读者—写者问题不同,信号量机制它增加了一个限制,即最多允许RN个读者同时读。为此,又引入了一个信号量L,并赋予初值为RN,通过执行wait(L,1,1)操作,来控制读者的数目,每当有一个读者进入时,就要执行wait(L,1,1)操作,使L的值减1。当有RN个读者进入读后,L便减为0,第RN+1个读者要进入读时,必然会因wait(L,1,1)操作失败而堵塞。对利用信号量来解决读者—写者问题的描述如下:
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验二读者写者问题实验报告一、实验目的Windows2000/XP提供了互斥量(mutex)、信号量(semapore)、事件(event)等三种同步对象和相应的系统调用,用于线程的互斥与同步。

通过对读者写者问题的调试,了解Windows2000/XP中的同步机制。

二、实验内容及实验步骤利用Windows2000/XP信号量机制,实现读者写者问题。

在Windows 2000环境下,创建一个控制台进程,此进程包含n个线程。

用这n个线程来表示n个读者或写者。

每个线程按相应测试数据文件(后面有介绍)的要求进行读写操作。

用信号量机制分别实现读者优先和写者优先的读者-写者问题。

读者-写者问题的读写操作限制(包括读者优先和写者优先):写-写互斥,即不能有两个写者同时进行写操作。

读-写互斥,即不能同时有一个线程在读,而另一个线程在写。

读-读允许,即可以有一个或多个读者在读。

读者优先的附加限制:如果一个读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。

写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态才能开始读操作。

运行结果显示要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结果读写操作时分别显示一行提示信息,以确定所有处理都遵守相应的读写操作限制。

三、实验结果及分析图2.1 选择界面第一字段为一个正整数,表示线程序号。

第二字段表示相应线程角色,R 表示读者是,W 表示写者。

第三字段为一个正数,表示读写操作的开始时间。

线程创建后,延时相应时间(单位为秒)后发出对共享资源的读写申请。

第四字段为一个正数,表示读写操作的持续时间。

当线程读写申请成功后,开始对共享资源的读写操作,该操作持续相应时间后结束,并释放共享资源。

下面是一个测试数据文件的例子:1 R 3 52 W 4 53 R 5 24 R 6 55 W 5.1 3测试结果如下:图2.2 读者优先运行结果图2.3 写者优先运行结果分析如下:将所有的读者和所有的写者分别放进两个等待队列中,当读允许时就让读者队列释放一个或多个读者,当写允许时,释放第一个写者操作。

读者优先:如果没有写者正在操作,则读者不需要等待,用一个整型变量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。

附:源代码如下:#include "windows.h"#include <conio.h>#include <stdlib.h>#include <fstream.h>#include <io.h>#include <string.h>#include <stdio.h>#define READER 'R' // 读者#define WRITER 'W' // 写者#define INTE_PER_SEC 1000 // 每秒时钟中断数目。

#define MAX_THREAD_NUM 64 // 最大线程数目#define MAX_FILE_NUM 32 // 最大数据文件数目#define MAX_STR_LEN 32 // 字符串长度int readcount=0; // 读者数目int writecount=0; // 写者数目CRITICAL_SECTION RP_Write; //临界区CRITICAL_SECTION cs_Write;CRITICAL_SECTION cs_Read;struct ThreadInfo{int serial; // 线程序号char entity; //线程类别(判断读者线程还是写者线程)double delay;double persist;};///////////////////////////////////////////////////////////////////////////// 读者优先--读者线程//p:读者线程信息void RP_ReaderThread(void* p){//互斥变量HANDLE h_Mutex;h_Mutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_readcount");DWORD wait_for_mutex; //等待互斥变量所有权DWORD m_delay; // 延迟时间DWORD m_persist; // 读文件持续时间int m_serial; //线程序号//从参数中获得信息m_serial=((ThreadInfo*)(p))->serial;m_delay=(DWORD)(((ThreadInfo*)(p))->delay*INTE_PER_SEC);m_persist=(DWORD)(((ThreadInfo*)(p))->persist*INTE_PER_SEC);Sleep(m_delay); //延迟等待printf("Reader thread %d sents the reading require.\n",m_serial);// 等待互斥信号,保证对readcount的访问、修改互斥wait_for_mutex=WaitForSingleObject(h_Mutex,-1);//读者数目增加Readcount++;if(readcount==1){//第一个读者,等待资源EnterCriticalSection(&RP_Write);}ReleaseMutex(h_Mutex); //释放互斥信号//读文件printf("Reader thread %d begins to read file.\n",m_serial);Sleep(m_persist);// 退出线程printf("Reader thread %d finished reading file.\n",m_serial);//等待互斥信号,保证对readcount的访问、修改互斥wait_for_mutex=WaitForSingleObject(h_Mutex,-1);//读者数目减少readcount--;if(readcount==0){//如果所有读者读完,唤醒写者LeaveCriticalSection(&RP_Write);}ReleaseMutex(h_Mutex); //释放互斥信号}///////////////////////////////////////////////////////////////////////////// 读者优先--写者线程//p:写者线程信息void RP_WriterThread(void* p){DWORD m_delay; // 延迟时间DWORD m_persist; // 写文件持续时间int m_serial; //线程序号//从参数中获得信息m_serial=((ThreadInfo*)(p))->serial;m_delay=(DWORD)(((ThreadInfo*)(p))->delay*INTE_PER_SEC);m_persist=(DWORD)(((ThreadInfo*)(p)) ->persist*INTE_PER_SEC); Sleep(m_delay); //延迟等待printf("Writer thread %d sents the writing require.\n",m_serial);// 等待资源EnterCriticalSection(&RP_Write);//写文件printf("Writer thread %d begins to Write to the file.\n",m_serial);Sleep(m_persist);// 退出线程printf("Writer thread %d finished Writing to the file.\n",m_serial);//释放资源LeaveCriticalSection(&RP_Write);}///////////////////////////////////////////////////////////////////////////// 读者优先处理函数//file:文件名void ReaderPriority(char* file){DWORD n_thread=0; //线程数目DWORD thread_ID; //线程IDDWORD wait_for_all; //等待所有线程结束//互斥对象HANDLE h_Mutex;h_Mutex=CreateMutex(NULL,FALSE,"mutex_for_readcount");//线程对象的数组HANDLE h_Thread[MAX_THREAD_NUM];ThreadInfo thread_info[MAX_THREAD_NUM];readcount=0; // 初始化readcountInitializeCriticalSection(&RP_Write); //初始化临界区ifstream inFile;inFile.open(file); //打开文件printf("Reader Priority:\n\n");while(inFile){//读入每一个读者、写者的信息inFile>>thread_info[n_thread].serial;inFile>>thread_info[n_thread].entity;inFile>>thread_info[n_thread].delay;inFile>>thread_info[n_thread++].persist;inFile.get( );}for(int i=0;i< (int)(n_thread);i++){if(thread_info[i].entity==READER || thread_info[i].entity=='R'){h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_ReaderThread),&thread_info[i],0,&t hread_ID); //创建读者线程}else{//创建写者线程h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_WriterThread),&thread_info[i],0,&th read_ID);}}//等待所有线程结束wait_for_all=WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1);printf("All reader and writer have finished operating.\n");}///////////////////////////////////////////////////////////////////////////// 写者优先--读者线程//p:读者线程信息void WP_ReaderThread(void* p){//互斥变量HANDLE h_Mutex1;h_Mutex1=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex1"); HANDLE h_Mutex2;h_Mutex2=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex2");DWORD wait_for_mutex1; //等待互斥变量所有权DWORD wait_for_mutex2;DWORD m_delay; // 延迟时间DWORD m_persist; // 读文件持续时间int m_serial; //线程序号//从参数中获得信息m_serial=((ThreadInfo*)(p))->serial;m_delay=(DWORD)(((ThreadInfo*)(p))->delay*INTE_PER_SEC);m_persist=(DWORD)(((ThreadInfo*)(p)) ->persist*INTE_PER_SEC);Sleep(m_delay); //延迟等待printf("Reader thread %d sents the reading require.\n",m_serial);wait_for_mutex1= WaitForSingleObject(h_Mutex1,-1);//进入读者临界区EnterCriticalSection(&cs_Read);// 阻塞互斥对象mutex2,保证对readcount的访问、修改互斥wait_for_mutex2= WaitForSingleObject(h_Mutex2,-1);//修改读者数目readcount++;if(readcount==1){//如果是第一个读者,等待写者写完EnterCriticalSection(&cs_Write);}ReleaseMutex(h_Mutex2); //释放互斥信号mutex2 // 让其他读者进入临界区LeaveCriticalSection(&cs_Write);ReleaseMutex(h_Mutex1);//读文件printf("Reader thread %d begins to read file.\n",m_serial);Sleep(m_persist);// 退出线程printf("Reader thread %d finished reading file.\n",m_serial);// 阻塞互斥对象mutex2,保证对readcount的访问、修改互斥wait_for_mutex2= WaitForSingleObject(h_Mutex2,-1);readcount--;if(readcount==0){// 最后一个读者,唤醒写者LeaveCriticalSection(&cs_Write);}ReleaseMutex(h_Mutex2); //释放互斥信号}///////////////////////////////////////////////////////////////////////////// 写者优先--写者线程//p:写者线程信息void WP_WriterThread(void* p){DWORD m_delay; // 延迟时间DWORD m_persist; // 写文件持续时间int m_serial; //线程序号DWORD wait_for_mutex3;//互斥对象HANDLE h_Mutex3;h_Mutex3= OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex3");//从参数中获得信息m_serial=((ThreadInfo*)(p))->serial;m_delay=(DWORD)(((ThreadInfo*)(p))->delay*INTE_PER_SEC);m_persist=(DWORD)(((ThreadInfo*)(p))->persist*INTE_PER_SEC); Sleep(m_delay); //延迟等待printf("Writer thread %d sents the writing require.\n",m_serial);// 阻塞互斥对象mutex3,保证对writecount的访问、修改互斥wait_for_mutex3= WaitForSingleObject(h_Mutex3,-1);writecount++; //修改读者数目if(writecount==1){//第一个写者,等待读者读完EnterCriticalSection(&cs_Read);}ReleaseMutex(h_Mutex3);//进入写者临界区EnterCriticalSection(&cs_Write);//写文件printf("Writer thread %d begins to Write to the file.\n",m_serial);Sleep(m_persist);// 退出线程printf("Writer thread %d finishing Writing to the file.\n",m_serial);//离开临界区LeaveCriticalSection(&cs_Write);// 阻塞互斥对象mutex3,保证对writecount的访问、修改互斥wait_for_mutex3= WaitForSingleObject(h_Mutex3,-1);writecount--; //修改读者数目if(writecount==0){//写者写完,读者可以读LeaveCriticalSection(&cs_Read);}ReleaseMutex(h_Mutex3);}///////////////////////////////////////////////////////////////////////////// 写者优先处理函数//file:文件名void WriterPriority(char* file){DWORD n_thread=0; //线程数目DWORD thread_ID; //线程ID DWORD wait_for_all; //等待所有线程结束//互斥对象HANDLE h_Mutex1;h_Mutex1=CreateMutex(NULL,FALSE,"mutex1");HANDLE h_Mutex2;h_Mutex2=CreateMutex(NULL,FALSE,"mutex2");HANDLE h_Mutex3;h_Mutex3=CreateMutex(NULL,FALSE,"mutex3");//线程对象HANDLE h_Thread[MAX_THREAD_NUM];ThreadInfo thread_info[MAX_THREAD_NUM];readcount=0; // 初始化readcount writecount=0; // 初始化writecount InitializeCriticalSection(&cs_Write); //初始化临界区InitializeCriticalSection(&cs_Read);ifstream inFile;inFile.open(file); //打开文件printf("Writer Priority:\n\n");while(inFile){//读入每一个读者、写者的信息inFile>>thread_info[n_thread].serial;inFile>>thread_info[n_thread].entity;inFile>>thread_info[n_thread].delay;inFile>>thread_info[n_thread++].persist;inFile.get( );}for(int i=0;i< (int)(n_thread);i++){if (thread_info[i].entity==READER || thread_info[i].entity=='R'){//创建读者线程h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_WriterThread),&thread_info[i],0,&th read_ID);}else{//创建写者线程h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(WP_WriterThread),&thread_info[i],0,&t hread_ID);}}//等待所有线程结束wait_for_all=WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1);printf("All reader and writer have finished operating.\n");}/////////////////////////////////////////////////////////////////////////////////主函数int main(int argc,char* argv[]){char ch;while (true){//打印提示信息printf("************************************************\n");printf(" 1:Reader Priority\n");printf(" 2:Writer Priority\n");printf(" 3:Exit Priority\n");printf("************************************************\n");printf("Enter your choice(1,2 or 3): ");//如果输入信息不正确,继续输入do{ch=(char)_getch( );}while(ch != '1' &&ch != '2' && ch != '3');system("cls");//选择3,返回if(ch=='3')return 0;//选择1,读者优先else if(ch=='1')ReaderPriority("thread.dat");//选择2,写者优先elseWriterPriority("thread.dat");//结束printf("\nPress Any Key To Continue: ");_getch( );system("cls");}return 0;}。

相关文档
最新文档