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

合集下载

读者写者实验报告

读者写者实验报告

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

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

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

实验环境:
- 操作系统: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)操作失败而堵塞。对利用信号量来解决读者—写者问题的描述如下:

操作系统原理实验报告

操作系统原理实验报告

《操作系统原理》实验报告班级::学号:指导老师:目录:实验题目:实验一线程创建与撤销 (2)实验题目:实验二线程同步 (6)实验题目:实验三线程互斥 (11)实验题目:实验四进程通信 (17)实验题目:实验五读者-写者问题 (22)实验题目:实验六进程调度 (38)实验题目:实验七存储管理之动态库 (52)实验题目:实验八存储管理之存分配 (57)实验题目:实验九存储管理之页面置换算法 (70)实验题目:实验十设备管理 (85)实验题目:实验十一文件管理之文件读写 (99)实验题目:实验一线程创建与撤销完成人:XXX报告日期:2018年3月31日一、实验容简要描述(1)熟悉VC++、Visual Studio开发环境。

(2)使用相关函数创建和撤销线程。

(3)在一个进程中创建3个线程,名字分别为threada、threadb、threadc。

threada输出“hello world! ”。

threadb输出“My name is …”。

threadc输出“Please wait…”,然后sleep 5秒钟,接着输出“I wake up”。

二、程序设计1、设计思路该函数创建一个在调用进程的地址空间中执行的线程。

2、主要数据结构HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId);VOID ExitThread(DWORD dwExitCode);VOID Sleep(DWORD dwMilliseconds);VOID Sleep(DWORD dwMilliseconds);三、实验结果1、基本数据lpThreadAttributes:指向一个SECURITY_ATTRIBUTES结构,该结构决定了返回的句柄是否可被子进程继承。

读者写者问题实验报告

读者写者问题实验报告

读者写者问题实验报告引言读者写者问题是计算机科学中经典的同步问题之一,它涉及多线程编程中的资源竞争与同步机制。

通过对读者写者问题的研究,我们可以深入理解线程同步的重要性,并掌握解决并发编程中可能出现的竞争条件和死锁等问题的方法。

在本实验中,我们将设计并实现一个简单的读者写者问题的解决方案,并通过模拟多个读者和写者的并发访问来验证方案的正确性和效果。

问题描述读者写者问题可描述为:有一共享资源(如文件、数据库等),读者可同时访问共享资源进行读取操作,但写者在进行写入操作时,不可同时被其他任何读者或写者访问。

读者和写者的并发访问需要由线程同步机制来保证共享资源的一致性和完整性。

实验设计与实现为了解决读者写者问题,我们需要考虑以下几个关键点:1. 共享资源的访问控制我们可以使用互斥量(Mutex)来实现对共享资源的访问控制。

当一个线程访问共享资源时,它需要先获得互斥量的锁,如果锁已被其他线程占用,则线程进入等待状态,直到锁可用。

一旦线程完成对共享资源的访问,它将释放锁,以便其他线程继续访问。

2. 读者与写者的优先级在读者写者问题中,我们往往需要设定某个优先级规则,以确定读者和写者之间的调度顺序。

一种常见的策略是给予写者优先级,即当一个写者在等待访问共享资源时,其他读者都必须等待。

这样做是为了避免写者长时间等待,以免造成饥饿问题。

3. 记录读者和写者的数量为了控制读者和写者的并发访问,我们需要记录当前同时访问共享资源的读者和写者的数量。

我们可以使用整数变量来记录读者和写者的数量,并通过信号量来保证对这些计数变量的互斥访问。

4. 同步机制的设计在实现读者写者问题的解决方案时,我们需要考虑如何合理地使用互斥量和信号量,并结合优先级规则来实现读者和写者的同步。

这需要通过仔细的设计和调试来确保解决方案的正确性。

实验结果与分析我们基于上述设计实现了一个读者写者问题的解决方案,并进行了多次仿真实验。

实验环境•操作系统:Windows 10•编程语言:C++•编译器:GCC实验步骤1.编写读者和写者线程的代码,其中涉及到对共享资源的读取和写入操作,以及对计数变量和互斥量的访问操作。

实验2实验报告

实验2实验报告

实验2实验报告在我们探索知识的道路上,实验就像是一个个神秘的冒险,每一次都充满了未知和惊喜。

今天,我要和大家分享的就是实验 2 的奇妙之旅。

这次实验的主题是关于具体实验主题。

为了能顺利完成这个实验,我们可是做了充分的准备。

老师提前给我们讲解了实验的原理和步骤,让我们心里有了个底。

实验开始啦!我紧张又兴奋地摆弄着实验器材,就像一个即将出征的战士在检查自己的武器装备。

我小心翼翼地拿起实验器材名称,眼睛紧紧盯着它,生怕一个不小心就出了差错。

旁边的小伙伴也都全神贯注,教室里安静得只能听到我们紧张的呼吸声。

按照预定的步骤,我先进行了第一步操作。

这一步看起来简单,可真做起来还真不容易。

我得控制好操作的关键因素,稍微有一点偏差,可能就会影响整个实验结果。

我深吸一口气,告诉自己要稳住。

经过几次尝试,终于成功地完成了这一步,心里不禁小小地欢呼了一下。

接下来的步骤越来越复杂,我感觉自己的大脑在飞速运转。

在进行关键步骤名称的时候,我遇到了一个大难题。

怎么都达不到预期的效果,我急得满头大汗。

这时,我想起老师说过的话:“遇到问题不要慌,要冷静思考。

”于是,我停下手中的动作,重新审视了一遍实验步骤,仔细观察了其他同学的操作,终于发现了自己的错误。

原来是我在错误的具体方面上出了岔子。

找到问题所在后,我迅速调整,终于顺利地度过了这个难关。

在整个实验过程中,我和小伙伴们互相帮助,互相鼓励。

当有人遇到困难时,大家都会停下自己的工作,一起出谋划策。

这种团队合作的氛围让我感到特别温暖,也让我明白了在学习的道路上,我们不是一个人在战斗。

经过一番努力,实验终于接近尾声。

当看到最终的实验结果时,那种成就感简直无法用言语来形容。

我们的努力没有白费,实验成功啦!通过这次实验,我不仅学到了知识,还锻炼了自己的动手能力和解决问题的能力。

更重要的是,我明白了做任何事情都要有耐心、细心,遇到困难不能轻易放弃。

这就是我的实验 2 之旅,充满了挑战和收获。

读者写者问题实验报告

读者写者问题实验报告

实验二:读者写者问题一、实验要求在Windows 环境下,创建一个控制台进程,此进程包含n个线程。

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

每个线程按相应测试数据文件的要求进行读写操作。

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

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

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

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

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

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

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

流程图如图1、图2、图3、图4所示。

图1 流程图1图2 流程图2图3 流程图3图4 流程图4二、测试数据文件格式测试数据文件包括n行测试数据,分别描述创建的n个线程是读者还是写者,以及读写操作的开始时间和持续时间。

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

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

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

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

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

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

下面是一个测试数据文件的例子:1 R 3 52 W 4 53 R 5 24 R 6 55 W 5.1 3三、实验结果1、初始化界面2、读者优先3、写者优先。

操作系统读者写者实验报告

操作系统读者写者实验报告

操作系统读者写者实验报告一、实验目的通过实验理解读者写者问题的实现原理,掌握相关的同步机制,实现读者写者问题的经典解法,并对比不同解法的优缺点。

二、实验原理1.读者写者问题读者写者问题是指在多个线程同时读写一个共享数据的情况下可能出现的问题。

其问题的核心在于多个读线程可以同时读,但只能有一个写线程能够写,并且在写操作过程中不能有任何的读操作。

2.互斥与同步为了解决读者写者问题,在多线程并发读写共享数据时,需要使用互斥与同步机制来保证数据的完整性和一致性。

-互斥:通过锁机制来保证只允许一个线程进入临界区,其他线程需要等待锁的释放。

-同步:通过信号量等机制来保证线程按照一定顺序执行。

三、实验步骤本次实验中将实现两个版本的读者写者问题解决方案:一是使用互斥锁和条件变量,二是使用信号量。

1.使用互斥锁和条件变量(1)定义全局变量和互斥锁:共享数据、读者数目、互斥锁、写者条件变量、读者条件变量。

(2)初始化互斥锁和条件变量。

(3)写者线程的实现:获取互斥锁,判断当前是否有读者或写者,如果有则等待条件变量,然后进行写操作,释放互斥锁。

(4)读者线程的实现:获取互斥锁,判断是否有写者,如果有则等待条件变量,否则增加读者数目并释放互斥锁,进行读操作。

(5)测试程序的运行并输出结果。

2.使用信号量(1)定义全局变量和信号量:共享数据、读者信号量、写者信号量、用于保护读者数目和写者数目的互斥信号量。

(2)初始化信号量和互斥信号量。

(3)写者线程的实现:首先获取写者互斥信号量,然后获取写者信号量,进行写操作,释放写者信号量和写者互斥信号量。

(4)读者线程的实现:首先获取读者互斥信号量,然后增加读者数目,如果是第一个读者则获取写者信号量,然后进行读操作,释放读者信号量和读者互斥信号量,如果是最后一个读者则释放写者信号量。

(5)测试程序的运行并输出结果。

四、实验结果与分析通过对比两种解决方案,可以得出以下结论:1.使用互斥锁和条件变量的解决方案相对较为简单,但可能存在饥饿问题,即可能会导致一些线程一直无法访问共享资源。

实验二实验报告

实验二实验报告

实验二实验报告第一点:实验背景及目的实验二旨在探究实验室环境下,不同浓度下的化学反应速率,并对比分析不同反应物的反应性能。

本实验选择了一种常见的酸碱反应,通过改变反应物的浓度,观察反应速率的变化,从而深入了解化学反应机理,提高实验操作能力和科学素养。

实验过程中,首先对实验所需的仪器和试剂进行了详细的检查和准备,确保实验的准确性和安全性。

然后,根据实验设计,配制了不同浓度的反应溶液,并设置了对照组和实验组,以保证实验结果的科学性和可靠性。

在实验操作过程中,严格遵循实验规程,注意观察反应过程中的现象,如气体的产生、颜色的变化等,并及时记录数据。

在实验结束后,对实验数据进行了整理和分析,通过对比不同浓度下的反应速率,得出了实验结论。

第二点:实验结果与分析实验结果表明,在一定范围内,反应物的浓度与反应速率呈正相关。

即随着反应物浓度的增加,反应速率也相应增加。

这一结果与我们的预期一致,也与化学反应的基本原理相符。

分析实验原因,主要是由于反应物浓度的增加,增加了反应物分子之间的碰撞机会,从而提高了反应速率。

同时,我们也发现,在实验过程中,温度、压力等环境因素对反应速率也有一定的影响,但在本实验中,我们主要关注了反应物浓度对反应速率的影响。

此外,通过实验,我们还发现了一些问题,如实验数据的准确性、实验操作的规范性等,这些问题需要在今后的实验中加以改进和提高。

总之,本次实验取得了圆满的成功,不仅达到了实验目的,也提高了我们的实验能力和科学素养。

通过对实验结果的分析,我们对化学反应速率的影响因素有了更深入的了解,也为今后的学习和研究奠定了基础。

第三点:实验数据与讨论根据实验记录的数据,我们对不同浓度的反应溶液进行了反应速率的测量和比较。

实验数据表明,在实验条件下,反应速率随着反应物浓度的增加而显著增加。

具体来说,当反应物A的浓度从10mmol/L增加到50mmol/L时,反应速率从0.1mL/min增加到0.5mL/min。

读者写者问题实验报告

读者写者问题实验报告

北京电子科技学院(BESTI)实验报告课程:操作系统班级:0921 姓名:学号:成绩:指导教师:徐小青实验日期:2011.11.22 实验密级:/ 预习程度:代码实验时间:12:50-15:20 仪器组次:A04 必修/选修:必修实验序号:(一)实验名称:用信号量来实现读者-写者问题实验目的与要求:理解进程(或线程)及信号量的概念实验仪器:一、实验目的:理解进程(或线程)及信号量的概念二、实验内容:1、定义一个数据缓存buffer及用于实现同步互斥的信号量。

2、定义一个读者函数:●当有写者在占用buffer时,读者应该等待,直到写者不再使用该buffer。

●当有其他读者在占用buffer时,读者可对buffer进行读取操作。

●当buffer中有数据时,则从其中读取一个数据,并显示然后退出。

●当buffer中没有数据时,应等待,直到buffer中有数据可读。

3、定义一个写者函数●当有读者在占用buffer时,写者应该等待,直到所有的读者都退出为止。

●当有其他写者占用buffer时,该写者应该等待,直到占用buffer的写者退出为止。

●当buffer有空闲时,写者应该在buffer中写入一个数据并退出。

●当buffer满时,写者应该等待,直到buffer有空闲为止。

4、定义主函数,在其中可以任意创建读者与写者。

可根据用户输入创建读者或写者进程(线程)。

三、实验当堂完成内容:1,将设计好的思路以代码形式呈现,并调通。

2,将数据改变,看结果是否符合预期设想3,与同学交流,将代码完善。

四、设计思想:读进程:read(){P(Sr); 申请区域P(Scot); 锁定读者计数器first = first+1;if(first ==1)P(Sdoc);V(Scnt); 解锁读者计数器开始读;P(Scnt); 锁定读者计数器V(Sdoc);V(Scnt);V(Sr);}写进程:write(){P(sdoc);开始写;V(sdoc);}主函数设计思想:五、代码及具体解释:#include <stdlib.h>#include <windows.h>#include <stdio.h>#define P(S) WaitForSingleObject(S, INFINITE)// 这是Windows 下多线程工作的P 操作#define V(S) ReleaseSemaphore(S, 1, NULL)// 这是Windows 下多线程工作的V 操作const int RN = 5 ; // 所有读者总数(可以改变)const int WN = 3; // 所有写者总数(可以改变)HANDLE Sdoc; // 文档信号量——互斥量(临界区的信号量题目要求是1)HANDLE Sr; // 读者信号量——广义信号量(一次最多有多少个读者在读)HANDLE Scnt; // 保护g_cntReader 的互斥量(目前有多少读者正在读)int g_cntReader = 0; // 读者个数计数器// funcname : JustWait ( )// note: 显示一些信息,让后等待// ret val : void//// + Parameter :// [ int ] - nReader 读者(写者)编号,读者>0,写者<0// [ int ] - min 操作等待的最短时间// [ int ] - max 操作等待得最长时间,实际等待的时间介于两者之间// [ LPCSTR ] - info 要显示的信息void JustWait(int nReader, int min, int max, LPCSTR info);DWORD WINAPI Reader(LPVOID lpPara);DWORD WINAPI Writer(LPVOID lpPara);// 这是主函数void main(){Sdoc = CreateSemaphore(NULL, 1, 1, "Document");// 创建信号量初值,最大信号量值Sr = CreateSemaphore(NULL, 3, 3, "ReaderNumber"); // 一次最多允许3 个Scnt = CreateSemaphore(NULL, 1, 1, "ReaderCounterProtect");// 他也是一个互斥信号量,初值为 1HANDLE threads[RN+WN];for (int i=0; i<RN; i++) //不断创建读者线程threads[i] = CreateThread(0, 0, Reader, 0, 0, 0);for (int j=0; j<WN; j++)threads[j+RN] = CreateThread(0, 0, Writer, 0, 0, 0);WaitForMultipleObjects(RN+WN, threads, TRUE, INFINITE);}// 读者线程DWORD WINAPI Reader(LPVOID lpPara){// 注意是静态变量,可以使每来一个读者增加一static int reader_num = 1;int i = reader_num ++;int x=0;while (x<=5){JustWait(i, 1, 2, "我想读"); //1s的时候来,给2s的时间去读P(Sr); // 读者未满P(Scnt); // 锁定读者计数器printf("还有%d 个读者在读, 读者%d进入\n", g_cntReader, i);g_cntReader ++;if (g_cntReader == 1) // 如果是第一个读者{JustWait(i, 1, 2, "我是第一个!");P(Sdoc); // 锁定文档printf("读者%d说:有人在读,不可写文件\n", i);JustWait(i, 1, 2, "我可以读文件了!");V(Scnt); // 解锁读者计数器释放JustWait(i, 2, 5, "我在读");// 读ing…………JustWait(i, 1, 2, "我将要离开!");P(Scnt); // 锁定读者计数器g_cntReader --;if (g_cntReader == 0) // 如果是最后一个{JustWait(i, 1, 2, "我是最后一个!");printf("读者%d说:可以对文件操作了!~~~\n", i);V(Sdoc);// 解锁文档}printf("还有%d个读者在, 读者%d离开\n", g_cntReader, i);V(Scnt);// 解锁读者计数器V(Sr); // 离开JustWait(i, 5, 3, "结束");x++;printf("%d\n",x);}return 0;}DWORD WINAPI Writer(LPVOID lpPara){// 注意是静态变量,可以使每来一个写者减去一,注意初值是负值static int g_cnt = -1;int j = g_cnt --;while (1){JustWait(j, 2, 4, "我想写");// 锁定文档P(Sdoc);printf("\t写者%d说:文件正在修改不可操作\n", -j);JustWait(j, 4, 3, "写···"); // 写ing……JustWait(j, 1, 2, "写完了,离开");printf("写者%d说:可以对文件操作了\n", -j);V(Sdoc);// 解锁文档JustWait(j, 8, 4, "休息了");}return 0;}void JustWait(int nReader, int min, int max, LPCSTR info)//min为读者到来时间,max为读者离开时间{const int BASETIME = 1000;// 等待时间的基本量,以毫秒表示int wait_time = 0;// 实际等待得时间if (max==min) // 判断是为了避免%0错误,注意取随机值wait_time = min*BASETIME;//处理时间为0;elsechar s_out[128];// 最终显示的信息缓冲if (nReader > 0)// 读者大于0,写者小于0sprintf(s_out, "读者%d说: %s\n", nReader, info);elsesprintf(s_out, "\t写者%d说: %s\n", -nReader, info);printf(s_out);// 打印Sleep(wait_time);// 然后等待}//其设计思想是:读者在读,来了写着,创建写着线程,利用时间片区分他们。

实验3--读者-写者问题与进程同步

实验3--读者-写者问题与进程同步

实验3 读者/写者问题与进程同步3.1 实验目的理解临界区和进程互斥的概念,掌握用信号量和PV操作实现进程互斥的方法。

3.2 实验要求在linux环境下编写一个控制台应用程序,该程序运行时能创建N个线程〔或者进程〕,其中既有读者线程又有写者线程,它们按照事先设计好的测试数据进行读写操作。

请用信号量和PV操作实现读者/写者问题。

读者/写者问题的描述如下:有一个被许多进程共享的数据区,这个数据区可以是一个文件,或者主存的一块空间〔比方一个数组或一个变量〕,甚至可以是一组处理器寄存器。

有一些只读取这个数据区的进程〔reader〕和一些只往数据区中写数据的进程〔writer〕。

以下假设共享数据区是文件。

这些读者和写者对数据区的操作必须满足以下条件:读—读允许;读—写互斥;写—写互斥。

这些条件具体来说就是:〔1〕任意多的读进程可以同时读这个文件;〔2〕一次只允许一个写进程往文件中写;〔3〕如果一个写进程正在往文件中写,禁止任何读进程或写进程访问文件;〔4〕写进程执行写操作前,应让已有的写者或读者全部退出。

这说明当有读者在读文件时不允许写者写文件。

对于读者-写者问题,有三种解决方法:1、读者优先除了上述四个规则外,还增加读者优先的规定,当有读者在读文件时,对随后到达的读者和写者,要首先满足读者,阻塞写者。

这说明只要有一个读者活跃,那么随后而来的读者都将被允许访问文件,从而导致写者长时间等待,甚至有可能出现写者被饿死的情况。

2、写者优先除了上述四个规则外,还增加写者优先的规定,即当有读者和写者同时等待时,首先满足写者。

当一个写者声明想写文件时,不允许新的读者再访问文件。

3、无优先除了上述四个规则外,不再规定读写的优先权,谁先等待谁就先使用文件。

实验步骤算法分析有同学认为,可以将文件视为临界资源,使用临界资源的代码就构成临界区,为了对临界区进行管理,只需设置一个互斥信号量r_w_w,读或者写之前执行P(r_w_w),之后执行V(r_w_w)即可,从而得到图3-1所示的算法描述。

读者写者问题实验报告

读者写者问题实验报告

读者写者问题实验报告1.实验目的:掌握读者写者问题的基本概念和操作实现方法。

2.实验原理:(1)读者写者问题:1.读者优先:若读者进程正在读文件,写者进程需等待。

2.写者优先:若写者进程正在写文件,读者进程需等待。

3.公平竞争:读写者进程均有机会访问文件。

(2)进程同步:1.信号量:能够同步进程的执行,性能较好。

2.互斥量:能够同步进程的执行,提供了更细粒度的控制。

3.条件变量:让进程能够进行相互之间的协作。

3.实验内容:(1)依照读者写者问题的操作实现方法,采用信号量机制,编写读者进程和写者进程。

(2)测试不同读者写者优先级下程序的执行情况。

4.实验步骤:(1)设计程序架构:1.使用信号量实现读者写者访问文件的同步操作;2.设计Readers和Writers两个类分别实现读者和写者进程的操作。

(2)实现程序:1.编写读者进程,在进程对文件进行读操作之前使用信号量P操作,读取完成后使用信号量V操作;2.编写写者进程,在进程对文件进行写操作之前使用信号量P操作,写入完成后使用信号量V操作;3.设计信号量的初始值,以实现不同读者写者优先级下程序的执行情况。

(3)测试程序:在有多个读者进程和多个写者进程的情况下,测试不同读者写者优先级下程序的执行情况。

5.实验结果:(1)读者优先:读者优先的情况下,不管读者进程和写者进程的数量如何设置,读者总是有后进先出的机会访问文件。

(2)写者优先:写者优先的情况下,不管读者进程和写者进程的数量如何设置,写者总是有先进先出的机会访问文件。

(3)公平竞争:公平竞争的情况下,读者或写者进程均有机会访问文件。

6.实验结论:(1)在实现读者写者问题的过程中,需要采用进程同步技术来确保进程之间的正确协作。

(2)信号量提供了一种较为有效的进程同步机制,能够满足读者写者问题的操作需求。

(3)采用不同的优先级设置,可以使读者写者进程之间实现不同的访问策略,进而实现不同的访问效果。

读者写者问题测试结果分析

读者写者问题测试结果分析

测试结果分析测试数据:程序菜单界面:读者优先结果:读者优先结果分析:根据测试数据及读者优先原则可知,线程1R在第2s先执行,当他执行了1s后,线程2w发出申请,但是被阻塞,实现读写互斥,然后,线程4R在第5s时发出申请,并被准许访问数据区,线程3R在第6s时发出申请并被准许访问数据区,同时实现了多个读者线程1R、3R、4R三个读者线程同时读数据允许,在第4s 时5w发出申请,但是被阻塞。

直到第10s时三个读者线程全部执行完成,2w 线程开始写操作,并且在它完成之前,写者线程5w仍然处于阻塞的状态,从而实现了两个写者进程之间的互斥。

写者优先结果:写者优先结果分析:根据测试数据及写者优先原则可知,读者线程1R在第2s时先执行,当读者线程执行1s后,线程2w发出申请,但是读者线程正在进行,所以写者线程2w被阻塞,实现了读写互斥,然后在第4s时,写者线程5w申请,但是1R未执行完成,所以线程5W被阻塞,接下来,线程4R和线程3R分别在第5s和第6s发出读请求,但是被阻塞,线程1R完成后,线程2W开始执行,执行完成后,虽然是3R、4R发出过申请,但是由于是写者优先,故5W开始执行,执行完成之后才开始按照时间先后顺序执行4R和3R读者线程,此时也实现了多个读者同时读数据的操作。

实验总结:本次实验主要是涉及了互斥信号量机制,允许多个进程同时读一个共享对象,因为读操作不会使数据文件混乱,但不允许写进程和读进程同时访问共享对象,因为这些访问会引起混乱,实验内容和所需知识都属于操作系统初级阶段,尤其是在具体系统平台下进行具体实现,但是实验代码熟悉起来比较困难,代码编程修改过程中遇见很多问题,也花费了大量的时间。

在实验的过程中,通过通过画流程图,单步跟踪,以及仔细阅读代码都得到了解决,而且也对实验程序进行了简化和修改。

通过实验,个人进一步对于互斥信号量机制和进程相关同步问题加深了理解。

操作系统试验讲解

操作系统试验讲解
// 提取这个进程的 ID DWORD dwIdThis=GetCurrentProcessId();
// 获得这一进程和报告所需的版本,也可以发送 0 以便指明这一进程 DWORD dwVerReq= GetProcessVersion(dwIdThis); WORD wMajorReq=(WORD)(dwVerReq>16) ; WORD wMinorReq=(WORD)(dwVerReq & 0xffff) ;
// procterm 项目 # include <windows.h> # include <iostream> # include <stdio.h> #include <iostream.h> static LPCTSTR g_szMutexName = "w2kdg.ProcTerm.mutex.Suicide" ;
<< ", Clone ID:" << nClone<< endl;
//Sleep(500) ; Sleep(4000);
// 检查是否有创建子进程的需要 const int c_nCloneMax=25; if (nClone < c_nCloneMax) {
StartClone(nClone) ;// 发送新进程的命令行和克隆号 }
进程可使用退出代码将终止方式通知给调用 GetExitCodeProcess() 的其他 进程。同时, GetProcessTimes(函) 数可向主调者显示进程的终止时间。 步骤 4:编译并执行 1-3.exe 程序, 其运行结果: 1) Creating the child process. 表示:正在创建一个子进程。 2)Telling the child process to quit. 表示:指令子进程终止。

常见的实验报告撰写问题及其解决方案

常见的实验报告撰写问题及其解决方案

常见的实验报告撰写问题及其解决方案实验报告是科学研究和实验成果的总结和归纳,对于科研工作者来说具有重要的意义。

然而,在实际操作中,我们常常会遇到一些问题,如何填写实验报告,如何组织语言,如何展示数据等等。

本文将针对常见的实验报告撰写问题进行探讨,并提供解决方案。

一、实验结果表达模糊不清实验报告的一个重要部分是实验结果的表达。

实验结果的表达是否清晰直接影响读者对研究成果的理解和评价。

常见的问题如下:1.未明确结果有些实验报告中,作者并未明确展示实验结果。

例如,仅仅列出了数据,却未对数据进行解释或分析,让读者不明白这些数据的意义。

为了解决这个问题,作者可以在数据的周围加上相关的文字说明,解释数据的意义和结果。

2.缺少图表支持有些实验报告没有使用图表来展示实验结果,而是将所有结果堆砌在一起,给读者带来困惑。

为了解决这个问题,作者可以使用图表来展示实验结果,帮助读者更好地理解和记忆实验结果。

同时,还可以使用表格来整理和比较数据,使得结果更加清晰明了。

二、实验过程描述不准确实验报告中实验过程的描述是关键之一,它决定了读者是否能够复制实验并得到相似的结果。

常见的问题如下:1.遗漏重要步骤有些实验报告在描述实验过程时,会遗漏一些重要的步骤,导致读者无法准确复制实验。

为了解决这个问题,作者需要仔细检查实验过程的描述,确保每个步骤都得到了详细说明,包括所使用的材料、实验操作的步骤和时间等。

2.描述模糊不清有些实验报告对实验过程的描述模糊不清,使用词汇不准确,使得读者无法理解实验的具体步骤。

为了解决这个问题,作者可以使用更加具体和准确的词汇来描述实验过程,并结合图表等辅助材料,帮助读者更好地理解实验的进行。

三、实验结论推理不充分实验报告的结论是实验结果的总结和归纳,它需要基于实验数据进行推导和分析。

常见的问题如下: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;}。

相关文档
最新文档