模拟写优先的读者写者问题
进程同步模拟设计——读者和写者问题
附件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)对实验题的评价和改进意见,请你推荐设计题目。
读者写者问题描述
读者写者问题描述嘿,你问读者写者问题啊?那我给你讲讲哈。
咱就说啊,这读者写者问题呢,就好比一个图书馆。
有很多人想去看书,这就是读者。
还有人想去写书,那就是写者。
有一回啊,我去图书馆。
那里面好多人都在安静地看书呢。
这时候就相当于有很多读者在享受知识。
突然,有个作家模样的人来了,他想找个地方坐下来写书。
这就是写者出现了。
这时候问题就来了。
如果读者和写者同时在图书馆里,会咋样呢?如果读者一直在看书,写者就没办法好好写书,因为他会觉得被打扰了。
反过来,如果写者一直在写书,读者也没办法好好看书,因为他们不知道啥时候能看到新的内容。
就像我在图书馆里,我正看得入迷呢,突然那个作家开始大声地思考他的情节,哎呀,那可把我烦死了。
我就想,你能不能安静点啊,让我好好看书嘛。
这就像读者希望写者不要打扰他们一样。
那怎么办呢?就得有个规则。
比如说,让写者先等读者都看完书走了,他再开始写书。
或者让读者在写者写书的时候,稍微安静一点,不要弄出太大动静。
我记得有一次,我在图书馆里,有个写者特别有礼貌。
他进来的时候,看到很多读者,就悄悄地找了个角落坐下,等大家都看得差不多了,他才开始动笔。
这样大家都能和谐共处了。
读者写者问题就是要找到一个平衡,让读者能愉快地看书,写者也能安心地写书。
不能让一方太强势,影响了另一方。
就像在生活中,我们也会遇到类似的情况。
比如说,一个办公室里,有人在安静地工作,有人在讨论问题。
这时候就得互相体谅,不能太吵了,影响别人工作。
总之啊,读者写者问题就是要解决大家在共享资源的时候,如何和谐相处的问题。
嘿嘿,你明白了不?。
读者写者问题
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.读者—写者问题读者—写者问题(Readers-Writers problem)也是一个经典的并发程序设计问题,是经常出现的一种同步问题。
计算机系统中的数据(文件、记录)常被多个进程共享,但其中某些进程可能只要求读数据(称为读者Reader);另一些进程则要求修改数据(称为写者Writer)。
就共享数据而言,Reader和Writer是两组并发进程共享一组数据区,要求:(1)允许多个读者同时执行读操作;(2)不允许读者、写者同时操作;(3)不允许多个写者同时操作。
Reader和Writer的同步问题分为读者优先、弱写者优先(公平竞争)和强写者优先三种情况,它们的处理方式不同。
(1)读者优先。
对于读者优先,应满足下列条件:如果新读者到:①无读者、写者,新读者可以读;②有写者等待,但有其它读者正在读,则新读者也可以读;③有写者写,新读者等待。
如果新写者到:①无读者,新写者可以写;②有读者,新写者等待;③有其它写者,新写者等待。
单纯使用信号量不能解决读者与写者问题,必须引入计数器rc 对读进程计数;rc_mutex 是用于对计数器rc 操作的互斥信号量;write表示是否允许写的信号量;于是读者优先的程序设计如下:int rc=0; //用于记录当前的读者数量semaphore rc_mutex=1; //用于对共享变量rc 操作的互斥信号量semaphore write=1; //用于保证读者和写者互斥地访问的信号量void reader() /*读者进程*/do{P(rc_mutex); //开始对rc共享变量进行互斥访问rc ++; //来了一个读进程,读进程数加1if (rc==1) P(write);//如是第一个读进程,判断是否有写进程在临界区,//若有,读进程等待,若无,阻塞写进程V(rc_mutex); //结束对rc共享变量的互斥访问读文件;P(rc_mutex); //开始对rc共享变量的互斥访问r c--; //一个读进程读完,读进程数减1if (rc == 0) V(write);//最后一个离开临界区的读进程需要判断是否有写进程//需要进入临界区,若有,唤醒一个写进程进临界区V(rc_mutex); //结束对rc共享变量的互斥访问} while(1)void writer() /*写者进程*/do{P(write); //无读进程,进入写进程;若有读进程,写进程等待写文件;V(write); //写进程完成;判断是否有读进程需要进入临界区,//若有,唤醒一个读进程进临界区} while(1)读者优先的设计思想是读进程只要看到有其它读进程正在读,就可以继续进行读;写进程必须等待所有读进程都不读时才能写,即使写进程可能比一些读进程更早提出申请。
读者写者问题实验报告
读者写者问题实验报告引言读者写者问题是计算机科学中经典的同步问题之一,它涉及多线程编程中的资源竞争与同步机制。
通过对读者写者问题的研究,我们可以深入理解线程同步的重要性,并掌握解决并发编程中可能出现的竞争条件和死锁等问题的方法。
在本实验中,我们将设计并实现一个简单的读者写者问题的解决方案,并通过模拟多个读者和写者的并发访问来验证方案的正确性和效果。
问题描述读者写者问题可描述为:有一共享资源(如文件、数据库等),读者可同时访问共享资源进行读取操作,但写者在进行写入操作时,不可同时被其他任何读者或写者访问。
读者和写者的并发访问需要由线程同步机制来保证共享资源的一致性和完整性。
实验设计与实现为了解决读者写者问题,我们需要考虑以下几个关键点:1. 共享资源的访问控制我们可以使用互斥量(Mutex)来实现对共享资源的访问控制。
当一个线程访问共享资源时,它需要先获得互斥量的锁,如果锁已被其他线程占用,则线程进入等待状态,直到锁可用。
一旦线程完成对共享资源的访问,它将释放锁,以便其他线程继续访问。
2. 读者与写者的优先级在读者写者问题中,我们往往需要设定某个优先级规则,以确定读者和写者之间的调度顺序。
一种常见的策略是给予写者优先级,即当一个写者在等待访问共享资源时,其他读者都必须等待。
这样做是为了避免写者长时间等待,以免造成饥饿问题。
3. 记录读者和写者的数量为了控制读者和写者的并发访问,我们需要记录当前同时访问共享资源的读者和写者的数量。
我们可以使用整数变量来记录读者和写者的数量,并通过信号量来保证对这些计数变量的互斥访问。
4. 同步机制的设计在实现读者写者问题的解决方案时,我们需要考虑如何合理地使用互斥量和信号量,并结合优先级规则来实现读者和写者的同步。
这需要通过仔细的设计和调试来确保解决方案的正确性。
实验结果与分析我们基于上述设计实现了一个读者写者问题的解决方案,并进行了多次仿真实验。
实验环境•操作系统:Windows 10•编程语言:C++•编译器:GCC实验步骤1.编写读者和写者线程的代码,其中涉及到对共享资源的读取和写入操作,以及对计数变量和互斥量的访问操作。
实验一 读者写者问题
实习一:读者写者问题1实习要求在Windows2000环境下,创建一个控制台进程,此进程包含n个线程。
用这n个线程来表示n个读者或写者。
每个线程按相应测试数据文件(后面有介绍)的要求进行读写操作。
用信号量机制分别实现读者优先和写者优先的读者-写者问题。
读者-写者问题的读写操作限制(包括读者优先和写者优先):1)写-写互斥,即不能有两个写者同时进行写操作。
2)读-写互斥,即不能同时有一个线程在读,而另一个线程在写。
,3)读-读允许,即可以有一个或多个读者在读。
读者优先的附加限制:如果一个读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。
写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。
运行结果显示要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确定所有处理都遵守相应的读写操作限制。
2测试数据文件格式测试数据文件包括n行测试数据,分别描述创建的n个线程是读者还是写者,以及读写操作的开始时间和持续时间。
每行测试数据包括四个字段,各个字段间用空格分隔。
第一字段为一个正整数,表示线程序号。
第二字段表示相应线程角色,R表示读者,w表示写者。
第三字段为一个正数,表示读写操作的开始时间:线程创建后,延迟相应时间(单位为秒)后发出对共享资源的读写申请。
第四字段为一个正数,表示读写操作的持续时间。
当线程读写申请成功后,开始对共享资源的读写操作,该操作持续相应时间后结束,并释放共享资源。
下面是一个测试数据文件的例子:2 W 4 53 R 5 24 R 6 55 W 5.1 3注意在创建数据文件时,由于涉及到文件格式问题,最好在记事本中手工逐个键入数据,而不要拷贝粘贴数据,否则,本示例程序运行时可能会出现不可预知的错误。
3实习分析可以将所有读者和所有写者分别存于一个读者等待队列和一个写者等待队列中,每当读允许时,就从读者队列中释放一个或多个读者线程进行读操作;每当写允许时,就从写者队列中释放一个写者进行写操作。
读者写者问题_写者优先参考答案
}
}
void writer() /*写者进程*/
{
if(Rcount>0)
authFlag=0;
P(Wmutex);
......;
write; /* 执行写操作 */
......;
P(Wmutex);
P(Amutex)
while(waitAuthCount>0){
v(mutexAuth);
waitAuthCou
【vc++代码】
// testsemaphore.cpp : Defines the entry point for the console application.
// by西南大学计算机科学系周竹荣
//
#include"stdafx.h"
#include"windows.h"
Rmutex=CreateSemaphore(NULL,1,1,NULL);
Authmutex=CreateSemaphore(NULL,1,1,NULL);
Amutex=CreateSemaphore(NULL,1,1,NULL);
while(1){
Sleep(100);
srand((unsigned)time(NULL));
允许任意多的读进程同时读;
一次只允许一个写进程进行写操作;
如果有一个写进程正在进行写操作,禁止任何读进程进行读操作。
为了解决该问题,我们只需解决“写者与写者”和“写者与第一个读者”的互斥问题即
可,为此我们引入一个互斥信号量Wmutex,为了记录谁是第一个读者,我们用一个共享整
型变量Rcount 作一个计数器。而在解决问题的过程中,由于我们使用了共享变量Rcount,
读者写者问题写者优先参考答案完整版
读者写者问题写者优先参考答案HUA system office room 【HUA16H-TTMS2A-HUAS8Q8-HUAH1688】【写者优先】在读者、写者问题中,如果总有读者进程进行读操作,会造成写者进程永远都不能进行写操作(读者优先),即所谓的写者饿死现象。
给出读者、写者问题的另一个解决方案:即保证当有一个写者进程想写时,不允许读者进程再进入,直到写者写完为止,即写者优先。
让我们先回顾读者写者问题[1]:一个数据对象若被多个并发进程所共享,且其中一些进程只要求读该数据对象的内容,而另一些进程则要求写操作,对此,我们把只想读的进程称为“读者”,而把要求写的进程称为“写者”。
在读者、写者问题中,任何时刻要求“写者”最多只允许有一个执行,而“读者”则允许有多个同时执行。
因为多个“读者”的行为互不干扰,他们只是读数据,而不会改变数据对象的内容,而“写者”则不同,他们要改变数据对象的内容,如果他们同时操作,则数据对象的内容将会变得不可知。
所以对共享资源的读写操作的限制条件是:允许任意多的读进程同时读;一次只允许一个写进程进行写操作;如果有一个写进程正在进行写操作,禁止任何读进程进行读操作。
为了解决该问题,我们只需解决“写者与写者”和“写者与第一个读者”的互斥问题即可,为此我们引入一个互斥信号量Wmutex,为了记录谁是第一个读者,我们用一个共享整型变量Rcount 作一个计数器。
而在解决问题的过程中,由于我们使用了共享变量Rcount,该变量又是一个临界资源,对于它的访问仍需要互斥进行,所以需要一个互斥信号量Rmutex,算法如下:}}现在回到【写者优先】优先问题【写者优先】在读者、写者问题中,如果总有读者进程进行读操作,会造成写者进程永远都不能进行写操作(读者优先),即所谓的写者饿死现象。
给出读者、写者问题的另一个解决方案:即保证当有一个写者进程想写时,不允许读者进程再进入,直到写者写完为止,即写者优先。
读者-写者问题解答
2.读者—写者问题读者—写者问题(Readers-Writers problem)也是一个经典的并发程序设计问题,是经常出现的一种同步问题。
计算机系统中的数据(文件、记录)常被多个进程共享,但其中某些进程可能只要求读数据(称为读者Reader);另一些进程则要求修改数据(称为写者Writer)。
就共享数据而言,Reader和Writer是两组并发进程共享一组数据区,要求:(1)允许多个读者同时执行读操作;(2)不允许读者、写者同时操作;(3)不允许多个写者同时操作。
Reader和Writer的同步问题分为读者优先、弱写者优先(公平竞争)和强写者优先三种情况,它们的处理方式不同。
(1)读者优先。
对于读者优先,应满足下列条件:如果新读者到:①无读者、写者,新读者可以读;②有写者等待,但有其它读者正在读,则新读者也可以读;③有写者写,新读者等待。
如果新写者到:①无读者,新写者可以写;②有读者,新写者等待;③有其它写者,新写者等待。
单纯使用信号量不能解决读者与写者问题,必须引入计数器rc 对读进程计数;rc_mutex 是用于对计数器rc 操作的互斥信号量;write表示是否允许写的信号量;于是读者优先的程序设计如下:int rc=0; //用于记录当前的读者数量semaphore rc_mutex=1; //用于对共享变量rc 操作的互斥信号量semaphore write=1; //用于保证读者和写者互斥地访问的信号量void reader() /*读者进程*/do{P(rc_mutex); //开始对rc共享变量进行互斥访问rc ++; //来了一个读进程,读进程数加1if (rc==1) P(write);//如是第一个读进程,判断是否有写进程在临界区,//若有,读进程等待,若无,阻塞写进程V(rc_mutex); //结束对rc共享变量的互斥访问读文件;P(rc_mutex); //开始对rc共享变量的互斥访问r c--; //一个读进程读完,读进程数减1if (rc == 0) V(write);//最后一个离开临界区的读进程需要判断是否有写进程//需要进入临界区,若有,唤醒一个写进程进临界区V(rc_mutex); //结束对rc共享变量的互斥访问} while(1)void writer() /*写者进程*/do{P(write); //无读进程,进入写进程;若有读进程,写进程等待写文件;V(write); //写进程完成;判断是否有读进程需要进入临界区,//若有,唤醒一个读进程进临界区} while(1)读者优先的设计思想是读进程只要看到有其它读进程正在读,就可以继续进行读;写进程必须等待所有读进程都不读时才能写,即使写进程可能比一些读进程更早提出申请。
操作系统之读者与写者问题(C++)
printf("第%d位读者正在读。。。\n", myid);
Sleep(2000);//模拟读操作
printf("第%d位读者已完成\n", myid);
WaitForSingleObject(rc_mutex, INFINITE);//对rc互斥访问
ReleaseMutex函数的功能是释放互斥对象的控制权,可以理解为使一个特定的内核对象变为已通知状态。
4.测试及实验结果
4.1 实验结果
图4-1 第一次运行结果图
图4-2 第二次运行结果图
4.2 结果分析
根据图4-1的运行结果来分析,当第二位读者和第二位写者同时存在时,先运行的是写者进程,只有当写者进程完成操作后才能进行读者进程,根据图4-2的运行结果来分析,第一位读者进入后需等第四位写者完成写操作后才能开始读操作。总得来看,该程序得读者与写者得优先级其实是一样的,谁先创建的就谁先运行,但必须等上一个进程完成后才能运行下一个进程。
6.参考文献
[1]张玉生、刘炎、张亚红. C语言程序设计[M].上海交通大学出版社,2004
[2]陆丽娜.计算机操作系统[M].高等教育出版社. 2015.8
[3]李春葆.数据结构教程[M].清华大学出版社,2004
[4].陈向群,向勇等. Windows操作系统原理(第二版) [M]. 机械工业出版社,2004
rc -= 1;//读者数减1
if (rc == 0)
ReleaseMutex(w);//释放写互斥信号量
ReleaseMutex(rc_mutex);//释放互斥信号量rc_mutex
return 1;
读者写者问题中写者优先算法的实现
读者写者问题中写者优先算法的实现1. 简介读者写者问题是指多个线程(读者线程和写者线程)同时访问共享资源(如文件、数据库等)时可能发生的同步问题。
当多个线程同时读取共享资源时,不会产生冲突,但是当一个线程将共享资源写入时,其他线程不能读取或写入相同的资源,否则可能引发数据不一致的问题。
因此,需要一种合理的调度算法来解决读者写者问题。
其中,写者优先算法是一种常用的调度算法,它保证当有写者等待时,任何新到达的读者都必须等待。
只有当没有写者在等待时,读者才能获得对共享资源的访问权限。
本文将详细介绍写者优先算法的实现。
2. 写者优先算法实现原理写者优先算法的目标是尽快处理写者线程的请求,以保证共享资源的可用性和数据的一致性。
在写者优先算法中,当有写者线程请求访问共享资源时,读者线程需要等待,直到没有写者线程在等待为止。
这样可以保证写者线程尽快获得对资源的访问权限,以便进行写入操作。
具体实现写者优先算法的方法可以通过使用信号量和互斥锁来实现。
其中,互斥锁用于保证在任意时刻只能有一个线程访问共享资源,而信号量则用于控制写者线程和读者线程的访问权限。
3. 写者优先算法的实现步骤下面是使用写者优先算法解决读者写者问题的实现步骤:3.1 初始化信号量和互斥锁首先,需要初始化两个信号量和一个互斥锁,分别用于控制读者线程的访问权限、写者线程的访问权限和互斥访问共享资源。
这可以通过如下代码实现:mutex = Semaphore(1) # 互斥锁,用于控制对共享资源的互斥访问reader_count = Semaphore(1) # 读者数量,用于控制读者线程的访问权限writer_count = Semaphore(1) # 写者数量,用于控制写者线程的访问权限3.2 编写读者线程代码读者线程的代码如下所示:def reader():# 读者线程的入口函数while True:writer_count.acquire() # 获取写者数量的访问权限reader_count.acquire() # 获取读者数量的访问权限# 读者线程访问共享资源reader_count.release() # 释放读者数量的访问权限writer_count.release() # 释放写者数量的访问权限3.3 编写写者线程代码写者线程的代码如下所示:def writer():# 写者线程的入口函数while True:writer_count.acquire() # 获取写者数量的访问权限reader_count.acquire() # 获取读者数量的访问权限mutex.acquire() # 获取互斥访问共享资源的权限# 写者线程访问共享资源mutex.release() # 释放互斥访问共享资源的权限reader_count.release() # 释放读者数量的访问权限writer_count.release() # 释放写者数量的访问权限3.4 启动线程最后,需要创建并启动多个读者线程和写者线程,以测试写者优先算法的实现。
操作系统OS报告读者与写者问题(进程同步问题)
目录一、课程设计目的及要求 (1)二、相关知识 (1)三、题目分析 (2)四、概要设计 (4)五、代码及流程 (5)六、运行结果 (11)七、设计心得 (12)八、参考文献 (12)一、课程设计目的及要求读者与写者问题(进程同步问题)用n 个线程来表示n个读者或写者。
每个线程按相应测试数据文件的要求,进行读写操作。
请用信号量机制分别实现读者优先和写者优先的读者-写者问题。
读者-写者问题的读写操作限制:1)写-写互斥;2)读-写互斥;3)读-读允许;写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。
二、相关知识Windows API:在本实验中涉及的API 有:1线程控制:CreateThread 完成线程创建,在调用进程的地址空间上创建一个线程,以执行指定的函数;它的返回值为所创建线程的句柄。
HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, // SDDWORD dwStackSize, // initial stack sizeLPTHREAD_START_ROUTINE lpStartAddress, // threadfunctionLPVOID lpParameter, // thread argumentDWORD dwCreationFlags, // creation optionLPDWORD lpThreadId // thread identifier);2 ExitThread 用于结束当前线程。
VOID ExitThread(DWORD dwExitCode // exit code for this thread);3Sleep 可在指定的时间内挂起当前线程。
VOID Sleep(DWORD dwMilliseconds // sleep time);4信号量控制:WaitForSingleObject可在指定的时间内等待指定对象为可用状态;DWORD WaitForSingleObject(HANDLE hHandle, // handle to objectDWORD dwMilliseconds // time-out interval);hHandle为等待的对象,也就是实现同步或者互斥的对象。
案例模拟教学法在“读者和写者”问题中的应用
・
计 算 机辅 助 教 学 ・
案 例模 拟 教 学 法 在 “ 者 和 写者 " 读 问题 中 的应 用
王文 霞 , 王春 红
( 运城学 院计算机科学 与技术系 , 山西 摘 运城 040 ) 4 0 0
要: 本文就“ 者和 写者” 读 问题——“ 者优 先” 读 问题运 用案例模拟法做 了深入浅 出的分析 、 讨论 , 对如何运 用好案例模拟法 并
组织 过 程 :
() 堂上请 四位 同学组 成两 个队列 : 者队列 ( 1 课 读 两位 同学 )
和写者队列( 两位 同学 ) 。
( 由读者队列的队首和写者队列进 行争“ 资源 。 2 ) 书”
( 假设读者先争到 了, 3 ) 他所做 的动作 ① 申请 R acu t ed on 计数器资源 , P R tx 即 ( mue )  ̄ i ( edo n= 0 PR ue)/ 如果发现计数器为 0 f R acu t= ) (m t ; x , 表示其是第一位读者 , 么他就有权利 申请 “ 资源 。 那 书” ()ed on= edo n+ ;  ̄ a cu tR a cu t1 R ()(mue)  ̄V R t ; x , 对计数器做加 1 操作 。 , 释放计数器资源 , 以便另外读者使用 。
些 同学 为 “ 者 ” 写 。
计算机名词术语 : 一个 数据对象若被多个并发进程所共享 ,
且其 中一些进程 只要求读该数据对象 的内容 ,而另一些进程则 要求修改 它 , 对此 , 把那 些只想读 的进 程称之 为“ 者” 而把要 读 ; 求修改的进 程称为 “ 写者” 。
1 分 析 问题 ( 者 优 先 为 例 ) . 2 读
( e at n o o p t ce c n e h o g ; u c e g U i ri ; a x Y n h n 0 4 O ) D pr me t fC m u e S in e a d T c n l y Y n h n nv s yS n i u c e g 4 来 互斥“ 者” 间互斥使 用 R acu t 读 之 edo n 计数
读者写者问题实验报告
读者写者问题实验报告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读者线程,此时也实现了多个读者同时读数据的操作。
实验总结:本次实验主要是涉及了互斥信号量机制,允许多个进程同时读一个共享对象,因为读操作不会使数据文件混乱,但不允许写进程和读进程同时访问共享对象,因为这些访问会引起混乱,实验内容和所需知识都属于操作系统初级阶段,尤其是在具体系统平台下进行具体实现,但是实验代码熟悉起来比较困难,代码编程修改过程中遇见很多问题,也花费了大量的时间。
在实验的过程中,通过通过画流程图,单步跟踪,以及仔细阅读代码都得到了解决,而且也对实验程序进行了简化和修改。
通过实验,个人进一步对于互斥信号量机制和进程相关同步问题加深了理解。
读者写者问题-写者优先参考答案
读者写者问题-写者优先参考答案【写者优先】在读者、写者问题中,如果总有读者进程进行读操作,会造成写者进程永远都不能进行写操作(读者优先),即所谓的写者饿死现象。
给出读者、写者问题的另一个解决方案:即保证当有一个写者进程想写时,不允许读者进程再进入,直到写者写完为止,即写者优先。
让我们先回顾读者写者问题[1]:一个数据对象若被多个并发进程所共享,且其中一些进程只要求读该数据对象的内容,而另一些进程则要求写操作,对此,我们把只想读的进程称为“读者”,而把要求写的进程称为“写者”。
在读者、写者问题中,任何时刻要求“写者”最多只允许有一个执行,而“读者”则允许有多个同时执行。
因为多个“读者”的行为互不干扰,他们只是读数据,而不会改变数据对象的内容,而“写者”则不同,他们要改变数据对象的内容,如果他们同时操作,则数据对象的内容将会变得不可知。
所以对共享资源的读写操作的限制条件是:⏹允许任意多的读进程同时读;⏹一次只允许一个写进程进行写操作;如果有一个写进程正在进行写操作,禁止⋯⋯;P(Rmutex);Rcount = Rcount - 1;if (Rcount == 0) V(wmutex);V(Rmutex);}}void writer() /*写者进程*/{while (true){P(Wmutex);⋯⋯;write; /* 执行写操作 */⋯⋯;P(Wmutex);}}现在回到【写者优先】优先问题【写者优先】在读者、写者问题中,如果总有读者进程进行读操作,会造成写者进程永远都不能进行写操作(读者优先),即所谓的写者饿死现象。
给出读者、写者问题的另一个解决方案:即保证当有一个写者进程想写时,不允许读者进程再进入,直到写者写完为止,即写者优先。
【解题思路】在上面的读者写者问题基础上,做以下修改:⏹增加授权标志authFlag,当写者到来,发现有读者在读,则取消授权,然后等待缓冲区;⏹增加“等待授权计数器waitAuthCount”,写者离开时,如果waitAuthCount大于0,则迭代唤醒等待授权的读者;⏹读者到来,首先看授权标志,如果有授权标志,则继续,否则等待授权,即写者取消授权后,新来的读者不能申请缓冲区。
进程同步通信经典问题—读者写者问题的算法分析与设计
理论算法
进程同步通信经典问题一读者写者问题的算法分析与设计
曾思源,徐艳 (四川大学锦城学院计算机与软件学院,四川成都,611731)
摘要:本篇文章就读者-写者这一经典问题,利用信号量和count计数器,提出了其多种实现算法和思考解决问题的过 程。同时,本文也通过模拟验证了这些算法,发现其利弊,进而来对其进行了部分的优化。在文章的最后提出了实际生活 中该经典问题的应用场景。本文的讨论有利于让读者对该经典问题有更深刻的认识。 关键字:读者和写者;同步通信;PV操作算法
Classical problem of process synchronization Communication Algorithm analysis and design of reader and writer problem
Zeng Siyuan, Xu Yan (School of Computer and Software, Jincheng College, Sichuan University, Chengdu Sichuan, 611731)
Abstract: This paper uses semaphore to realize a variety of algorithms and problem solving processes for a classical problemnamed aReader -Writer” . At the same time, this paper finds out the advantages and disadvantages and optimizes it by Simulating the actual situation. At the end of the paper, the practical application scenario of the algorithm is presented. The discussion in this article is helpful for readers to have a deeper understanding of this. Keywords; Reader - Writer; Synchronous; Communicationalgorithms
采用“写优先”的策略演示“读者写者”问题(C_)
青岛理工大学操作系统课程设计报告院(系):计算机工程学院专业:计算机科学与技术专业学生姓名:滕同学班级:__软件102_学号: 201007195 题目:采用“写优先”的策略演示“读者-写者”问题起迄日期: 2013.7.8-2013.7.17 设计地点:网络中心计算机学院机房指导教师:吴老师2012—2013年度第 2 学期完成日期: 2013 年 7 月 17 日一、课程设计目的进行操作系统课程设计主要是在学习操作系统课程的基础上,在完成操作系统各部分实验的基础上,对操作系统的整体进行一个模拟,通过实践加深对各个部分的管理功能的认识,还能进一步分析各个部分之间的联系,最后达到对完整系统的理解。
同时,可以提高运用操作系统知识解决实际问题的能力;锻炼实际的编程能力、创新能力及团队组织、协作开发软件的能力;还能提高调查研究、查阅技术文献、资料以及编写软件设计文档的能力。
此次实验我选择的是经典的读者写者问题。
读写者问题的传统解决方案采用读优先策略,可能会造成后续的写者被随后而来的读者插队而长时间等待,直到全部读者进程运行完毕后,才可进行写操作。
为此,选择采用“写优先策略”解决读写者问题,希望通过此次课程设计实现利于写者工作的功能,加深对线程、进程及同步概念的理解。
通过研究经典的进程同步问题,实现对读者-写者问题的并发控制,掌握运用信号量解决“同类进程多次访问,而不同类的进程必须互斥访问资源”的控制问题。
此次实验我选择用比较大众的C#语言编写,因为C#中有semaphore类是对操作系统的semaphore很好的描述。
二、课程设计内容与要求1、设计目的:通过研究经典的进程进步问题,实现对读者-写者问题的并发控制。
2、说明:阅览室一次最多可以容纳20个人。
3、设计要求:1)读者与写者至少包括ID、进入内存时间、读写时间三项内容,可在界面上进行输入2)读者与写者均有二个以上,可在程序运行期间动态增加读者与写者3)可读取样例数据(要求存放在外部文件中),进行读者/写者、进入内存时间、读写时间的初始化4)要求将运行过程用可视化界面动态显示,可随时暂停,查看阅览室中读者/写者数目、读者等待队列、写者等待队列、读写时间、等待时间5)读写策略为:读写互斥、写写互斥、写优先(只要写者到达,就阻塞后续的所有读者,一旦阅览室无人,写者能最快进入阅览室;在写者未出阅读室之前,又有新的读者与写者到达,仍然是写者排在前面)三、系统分析与设计3.1 系统分析3.1.1 信息分析:写者优先程序实现写者优先进行写,本程序主要功能包括增加读者写者,时间的显示,动态的显示读写过程,暂停继续。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
process *p,*q;
input();
printf("\n以下输出各时间片进程状态\n");
printf("<运行时如需暂停请输入P>\n");
Sleep(1000);
while((process1!=NULL)||(process2!=NULL)||(process3!=NULL))
{
p->next=process2;
process2=process2->next;
p=p->next;
p->next=NULL;
readcount++;
}
if(t==1)
{
p=process3;
process3=process3->next;
q=q->next;
p->next=NULL;
}
fclose(fp);
p=process1;
process1=process1->next;
p->next=NULL;
free(p);
break;
default :
{
p=(process *)malloc(sizeof(process));
q->next=p;
fscanf(fp,"%d %c %d %d",&p->name,&p->type,&p->starttime,&p->needtime);
p->runtime=0;
}
}
if(readcount>0)
{
p->next=process2;
process2=process2->next;
p=p->next;
p->next=NULL;
readcount++;
}
if((readcount==0)&&(wait(mutex)==1))
p=process3;
if(process3==NULL)
{
p=process3=(process *)malloc(sizeof(process));
p->next=NULL;
t=1;
}
else
{
while(p->next!=NULL)
{
p=p->next;
printf("读写时间:");
scanf("%d",&p->needtime);
printf("\n");
p->runtime=0;
q=q->next;
p->next=NULL;
}
p=process1;
process1=process1->next;
p->next=NULL;
free(p);
break;
case 2:
if((fp=fopen("123.txt","r"))==NULL)
{
printf("文件打开失败!\n");
exit(0);
}
while(!(feof(fp)))
q->next=NULL;
t=1;
}
else
{
while(q->next!=NULL)
{
q=q->next;
}
}
j=(process *)malloc(sizeof(process));
j->next=process1;
/* while(process1->starttime==i)
scanf("%d",&a);
q->starttime=a+i;
printf("\n");
printf("读写时间:");
scanf("%d",&q->needtime);
q->runtime=0;
q->next=NULL;
if(process1!=NULL)
{
while(p->next!=NULL)
{
q->next=process1;
process1=process1->next;
q=q->next;
q->next=NULL;
j->next=process1;
if(process1==NULL)
break;
}
p=process1;
*/ while(p!=NULL)
free(p);
}
}
int wait(int &a)
{
if(a<=0)
{
return 0;
}
a--;
return 1;
}
void signal(int &a)
{
a++;
} Βιβλιοθήκη void Reader()
{
process *p;
int t=0;
}
}
void sort()
{
process *p,*q,*j,*k;
j=p=(process *)malloc(sizeof(process));
p->next=NULL;
k=q=(process *)malloc(sizeof(process));
q->next=NULL;
p->next=NULL;
free(p);
}
}
void Writer()
{
if((wait(mutex)==1)&&(process3==NULL))
{
process3=process2;
process2=process2->next;
process3->next=NULL;
k->next=NULL;
free(k);
if(process2!=NULL)
{
p->next=q;
}
else
process2=q;
}
void add(int i)
{
process *p,*q;
int a;
p=process1;
q=(process *)malloc(sizeof(process));
printf("\n请选择:");
aa:
fflush(stdin);
scanf("%d",&a);
switch(a)
{
case 1:
printf("输入进程数:");
int i,j;
scanf("%d",&i);
for(j=1;i>0;i--,j++)
}
else
{
q->next=process2;
process2=process2->next;
q=q->next;
q->next=NULL;
}
}
process2=j->next;
j->next=NULL;
free(j);
q=k->next;
while(process2!=NULL)
{
if((process2->type=='w')||(process2->type=='W'))
{
p->next=process2;
process2=process2->next;
p=p->next;
p->next=NULL;
{
p=(process *)malloc(sizeof(process));
q->next=p;
printf("第%d个进程:\n",j);
printf("进程序号:");
scanf("%d",&p->name);
printf("\n");
printf("输入错误,重新输入:");
goto aa;
}
}
void ready(int i)
{
process *p,*q,*j,*k;
p=process1;
q=process2;
int t=0;
if(process2==NULL)
{
q=process2=(process *)malloc(sizeof(process));
{
i++;
if(process1!=NULL)
ready(i);
//if(process3!=NULL)
//if((process3->type=='w')||(process3->type=='W'))