面向对象OS读者-写者问题
读者-写者问题(Reader-Writer Problem)

学号:课程设计题目用多线程同步方法解决读者-写者问题(Reader-Writer Problem)学院计算机科学与技术学院专业软件工程班级姓名指导教师2010 年 6 月日目录目录 (1)课程设计任务书 (1)正文 (2)1.设计目的与要求 (2)1.1设计目的 (2)1.2设计要求 (2)2.设计思想及系统平台 (2)2.1设计思想 (2)2.2系统平台及使用语言 (3)3.详细算法描述 (3)4.源程序清单 (6)5.运行结果与运行情况 (9)6.调试过程 (11)7.总结 (12)本科生课程设计成绩评定表 (13)课程设计任务书学生姓名:专业班级:指导教师:工作单位:计算机科学与技术学院题目: 用多线程同步方法解决读者-写者问题(Reader-Writer Problem)初始条件:1.操作系统:Linux2.程序设计语言:C语言3.设有20个连续的存储单元,写入/读出的数据项按增序设定为1-20这20个字符。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.技术要求:1)为每个读者/写者产生一个线程,设计正确的同步算法2)每个读者/写者对该存储区进行操作后,即时显示该存储区的全部内容、当前指针位置和读者/写者线程的自定义标识符。
3)读者应有3个以上,写者应有有两个以上。
4)多个读者/写者之间须共享对存储区进行操作的函数代码。
2.设计说明书内容要求:1)设计题目与要求2)总的设计思想及系统平台、语言、工具等。
3)数据结构与模块说明(功能与流程图)4)给出用户名、源程序名、目标程序名和源程序及其运行结果。
(要注明存储各个程序及其运行结果的主机IP地址和目录。
)5)运行结果与运行情况(提示: (1)连续存储区可用数组实现。
(2)编译命令可用:cc -lpthread -o 目标文件名源文件名(3)多线程编程方法参见附件。
)3. 调试报告:1) 调试记录2)自我评析和总结上机时间安排:18周一~ 五08:0 -12:00指导教师签名:年月日系主任(或责任教师)签名:年月日正文1.设计目的与要求1.1设计目的通过研究Linux的线程机制和信号量实现读者写者问题(Reader-Writer Problem )的并发控制。
操作系统——读者-写者问题的解决方法

操作系统——读者-写者问题的解决⽅法问题描述不允许Write进程和Read进程或其他Write进程同时访问⽂件,Read进程可以和其他Read进程同时访问。
分为三种类型。
读者优先要求:1.多个读者可以同时访问⽂件2.同⼀时间只允许⼀个写者访问⽂件3.读者和写者进程互斥解决⽅法:⽤⼀个readcounter记录是第⼏个读者在读,如果是第⼀个读者,则不能让写者写,需要⼀个锁。
因为readcounter是临界资源,也需要⼀个互斥量。
semaphore rc_mutex = 1, wmutex = 1;readcounter = 0;void writer{do{wait(wmutex);//writesignal(wmutex);}while(TRUE);}void reader{do{wait(rc_mutex);if(readcounter == 0) wait(wmutex);readcounter ++;signal(rc_mutex);// readwait(rc_mutex);readcounter --;if(!readcounter) signal(wmutex);signal(rc_mutex);}while(TRUE);}写者优先要求:1.读者写者互斥2.写者读者同时等待时,所有等待的写者优先,等所有写者结束后,读者才能读3.没有写者时,读者能同时读4.写者到来时,不会终⽌已经进⾏的读者操作解决⽅法:semaphore wc_mutex = 1, prior = 1; //写者计数器,优先信号量readcounter = 0, writercounter = 0;void writer{do{wait(wc_mutex); //申请更改wc的权限if(writercounter == 0) //如果是第⼀个写者,就申请优先权限wait(prior);writercounter ++;signal(wc_mutex);wait(wmutex);//writesignal(wmutex);wait(wc_mutex);writercounter --;if(!writercounter)signal(prior); //当最后⼀个写者操作完成后,释放优先级权限 signal(wc_mutex);}while(TRUE);}void reader{do{wait(prior); //先申请优先级权限,如果前⾯还有写者就等待wait(rc_mutex);if(readcounter == 0) wait(wmutex);readcounter ++;signal(rc_mutex);signal(prior); //释放优先级权限// readwait(rc_mutex);readcounter --;if(!readcounter) signal(wmutex);signal(rc_mutex);}while(TRUE);}读写均等semaphore prior = 1; //读者和写者都等待在⼀个队列上,实现读写均等readcounter = 0, writercounter = 0;void writer{do{wait(prior);wait(wmutex);//writesignal(wmutex);signal(prior);}while(TRUE);}void reader{do{wait(prior);wait(rc_mutex);if(readcounter == 0) wait(wmutex);readcounter ++;signal(rc_mutex);signal(prior);//readwait(rc_mutex);readcounter --;if(!readcounter) signal(wmutex);signal(rc_mutex);}while(TRUE);}有错误请指出!。
OS课程设计__读者写者

兰州交通大学操作系统课程设计课程:计算机操作系统题目:进程同步(读者--写者)班级:姓名:学号:指导教师:日期:2012年12月21日目录1题目 (1)2设计概述 (1)2.1问题描述 (1)2.2采用信号量机制 (1)3课程设计目的及功能 (1)3.1设计目的 (1)3.2设计功能 (1)4总体设计思想概述 (2)4.1功能流程图 (2)4.2开发平台及源程序的主要部分 (3)4.3数据结构 (3)4.4模块说明 (3)4.5源程序 (3)5测试用例,运行结果与运行情况分析 (12)5.1测试用例 (12)5.2运行结果 (12)5.3运行结果分析 (14)6总结与心得 (15)1题目进程同步模拟设计——读者和写者问题2设计概述2.1问题描述模拟用信号量机制实现读者和写者问题,即有两组并发进程:读者和写者,共享一组数据区,进行读写操作,要求任一时刻“写者”最多只允许一个,而“读者”则允许多个。
2.1.1要求允许多个读者同时执行读操作;不允许读者、写者同时操作;不允许多个写者同时操作。
2.1.2读者和写者的相互关系:2.2采用信号量机制1)Wmutex表示读写的互斥信号量,初值: Wmutex =1;2)公共变量Rcount表示“正在读”的进程数,初值:Rcount =0;3)Rmutex:表示对Rcount的互斥操作,初值:Rmutex=1。
3课程设计目的及功能3.1设计目的通过实验模拟读者和写者之间的关系,了解并掌握他们之间的关系及其原理。
由此增加对进程同步的问题的了解。
具体如下:1)掌握基本的同步互斥算法,理解读者和写者模型;2)了解windows中多线程(多进程)的并发执行机制,线程(进程)间的同步和互斥;3)学习使用windows中基本的同步对象,掌握相应的API。
3.2设计功能利用模拟用信号量机制实现读者和写者问题:通过用户控制读进程和写进程,反应读者和写者问题中所涉及的进程的同步与互斥。
操作系统课程设计--读者-写者问题

操作系统课程设计报告一、操作系统课程设计任务书读者-写者问题实现1设计目的通过实现经典的读者写者问题,巩固对线程及其同步机制的学习效果,加深对相关基本概念的理解,并学习如何将基本原理和实际设计有机的结合。
2 设计要求在Windows 2000/XP环境下,使用多线程和信号量机制实现经典的读者写者问题,每个线程代表一个读者或一个写者。
每个线程按相应测试数据文件的要求,进行读写操作。
请用信号量机制分别实现读者优先和写者优先的读者-写者问题。
读者-写者问题的读写操作限制:(1)写-写互斥,即不能有两个写者同时进行写操作(2)读-写互斥,即不能同时有一个读者在读,同时却有一个写者在写(3)读-读允许,即可以有二个以上的读者同时读读者优先的附加限制:如果一个读者申请进行读操作时已有另一读者正在进行读操作,则该读者可直接开始读操作。
写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。
运行结果显示要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确信所有处理都遵守相应的读写操作限制。
3 测试数据文件格式测试数据文件包括n 行测试数据,分别描述创建的n 个线程是读者还是写者,以及读写操作的开始时间和持续时间。
每行测试数据包括四个字段,各字段间用空格分隔。
第一字段为一个正整数,表示线程序号。
第二字段表示相应线程角色,R 表示读者是,W 表示写者。
第三字段为一个正数,表示读写操作的开始时间。
线程创建后,延时相应时间(单位为秒)后发出对共享资源的读写申请。
第四字段为一个正数,表示读写操作的持续时间。
当线程读写申请成功后,开始对共享资源的读写操作,该操作持续相应时间后结束,并释放共享资源。
下面是一个测试数据文件的例子:1 r 3 52 w 4 53 r 5 24 r 6 55 w 5.1 34 相关API函数CreateThread()在调用进程的地址空间上创建一个线程ExitThread()用于结束当前线程Sleep()可在指定的时间内挂起当前线程CreateMutex()创建一个互斥对象,返回对象句柄OpenMutex()打开并返回一个已存在的互斥对象句柄,用于后续访问ReleaseMutex()释放对互斥对象的占用,使之成为可用WaitForSingleObject()可在指定的时间内等待指定对象为可用状态InitializeCriticalSection()初始化临界区对象EnterCriticalSection()等待指定临界区对象的所有权LeaveCriticalSection()释放指定临界区对象的所有权文件系统的设计通过对文件系统的设计,加深理解文件系统的内部功能及内部实现。
OS:读者写者问题(写者优先+LINUX+多线程+互斥量+代码)

OS:读者写者问题(写者优先+LINUX+多线程+互斥量+代码)⼀. 引⼦最近想⾃⼰写个简单的 WEB SERVER ,为了先练练⼿,熟悉下在LINUX系统使⽤基本的进程、线程、互斥等,就拿以前学过的 OS 问题开开⼑啦。
记得当年学读者写者问题,尤其是写者优先的时候,那是真⼼纠结啊。
刚才还觉得理解了,过⼀会⼉⼜糊涂了。
现在重新再看,还是容易纠结。
没办法,⽤得少。
我把读者优先和写者优先都实现了⼀下。
选择性重看了⼩部分《unix⾼程》使⽤了多线程+互斥量实现。
⼆. 互斥量与信号量互斥量如其名,同⼀时间只能被⼀个线程占有,实现线程间对某种数据结构的互斥访问。
试图对⼀个已经加锁的互斥量加锁,会导致线程阻塞。
允许多个线程对同⼀个互斥量加锁。
当对互斥量解锁时,阻塞在该互斥量上的线程会被唤醒,它们竞争对该互斥量加锁,加锁成功的线程将停⽌阻塞,剩余的加锁失败于是继续阻塞。
注意到,谁将竞争成功是⽆法预料的,这⼀点就类似于弱信号量。
(强信号量把阻塞在信号量上的进程按时间排队,先进先出)互斥量区别于信号量的地⽅在于,互斥量只有两种状态,锁定和⾮锁定。
它不像信号量那样可以赋值,甚⾄可以是负值。
共性⽅⾯,我所体会到的就⼀句话,都是⽤来实现互斥的。
⾄于其它区别或联系,⽤不上,不作研究。
三. 读者优先只要有⼀个读者正在读,那么后续的读者都能⽴即读,不管有多少写者在等待。
可能导致写者饥饿。
1. 读者1) 写者写时,不可读2) 有别的读者正在读,可读2. 写者1) 有读者正在读,不可写2) 有写者正在写,不可写3) ⽆读者正在读,⽆写者正在写,可写四. 写者优先当新的写者希望写时,不允许该写者后续的读者访问数据区,但必须保证之前的读者读完。
1. 读者特点1) 有写者正在写或者等待写,须等到没有写者才能读2) 没有写者,可以读2. 写者特点1) 写者与写者互斥。
当其它写者正在写时,其它写者不能写。
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)操作失败而堵塞。对利用信号量来解决读者—写者问题的描述如下:
操作系统读者写者问题报告

操作系统读者写者问题报告
读者写者问题是一种典型的操作系统同步问题,其描述如下:有多个读者和写者同时访问共享资源,读者可以同时访问共享资源,但写者必须独占式的访问共享资源,即任何时刻只能有一个写者访问共享资源,且在写者访问共享资源的期间,任何读者都不得访问共享资源。
此外,读者在访问共享资源时不会修改共享资源,而写者则会对共享资源进行修改。
如何实现读者写者问题呢?简单来说,可以使用信号量机制来解决这个问题。
具体来说,可以使用两个信号量RdMutex和WrMutex,RdMutex用于锁定读者,在读者访问共享资源时,需要申请RdMutex信号量,如果有写者在访问共享资源,则RdMutex会阻止读者访问共享资源;而当最后一个读者结束访问共享资源时,需要释放RdMutex信号量,以便让其他等待的读者访问共享资源。
类似地,WrMutex用于锁定写者,在写者访问共享资源时,需要申请WrMutex信号量,如果有其他读者或者写者在访问共享资源,则WrMutex会阻止写者访问共享
资源;而当写者访问共享资源结束时,需要释放WrMutex信号量,以便让其他等待的写者访问共享资源。
除了信号量机制之外,还可以使用其他同步机制来解决读者写者问题,比如互斥量、条件变量等。
同时,操作系统还可以采用优化策略,比如写优先、读写优先等,来提高读写效率。
总之,读者写者问题是操作系统同步问题中的一个经典问题,其实现方式需要考虑多方面的因素,包括并发访问、同步机制、优化策略等,需要经过深入思考和有效实践才能得到较好的解决方案。
读者-写者问题的实现

《操作系统原理》课程设计任务书题目:读者-写者问题的实现学生姓名:学号:班级:_____________题目类型:软件工程(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、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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 ++; //来了一个读进程,读进程数加1
if (rc==1) P(write);//如是第一个读进程,判断是否有写进程在临界区,
//若有,读进程等待,若无,阻塞写进程
V(rc_mutex); //结束对rc共享变量的互斥访问
读文件;
P(rc_mutex); //开始对rc共享变量的互斥访问
r c--; //一个读进程读完,读进程数减1
if (rc == 0) V(write);//最后一个离开临界区的读进程需要判断是否有写进程//需要
进入临界区,若有,唤醒一个写进程进临界区
V(rc_mutex); //结束对rc共享变量的互斥访问
} while(1)
void writer() /*写者进程*/
do{
P(write); //无读进程,进入写进程;若有读进程,写进程等待写文件;
V(write); //写进程完成;判断是否有读进程需要进入临界区,
//若有,唤醒一个读进程进临界区
} while(1)
读者优先的设计思想是读进程只要看到有其它读进程正在读,就可以继续进行读;写进程必须等待所有读进程都不读时才能写,即使写进程可能比一些读进程更早提出申请。
该算法只要还有一个读者在活动,就允许后续的读者进来,该策略的结果是,如果有一个稳定的读者流存在,那么这些读者将在到达后被允许进入。
而写者就始终被挂起,直到没有读者为止。
(2)写者优先1。
为了解决以上问题,写者优先1的设计思想是在一个写者到达时如果有正在工作的读者,那么该写者只要等待正在工作的读者完成,而不必等候其后面到来的读者就可以进行写操作。
注意,该算法当一个写者在等待时,后到达的读者是在写者之后被挂起,而不是立即允许进入。
在读者优先的算法的基础上增加了一个排队信号量read,读、写进程在每次操作前都要等待read信号量。
写者优先1的程序设计如下:
int rc=0; //用于记录当前的读者数量
semaphore rc_mutex=1; //用于对共享变量rc 操作的互斥信号量
semaphore write=1; //用于保证读者和写者互斥地访问的信号量
semaphore read=1; //用于保证在写进程封锁其后续的读进程的信号量
void reader() /*读者进程*/
do{
P(read); //若有写进程,后续读进程等待,在read队列上排队P(rc_mutex); //开始对rc共享变量进行互斥访问
rc++; //来了一个读进程,读进程数加1
if rc=1 then P(write); //第一个读进程需要判断是否有写进程在临界区,若有,
//读进程需要等待,若没有,阻塞写进程
V(rc_mutex); //结束对rc共享变量的互斥访问
V(read);//从read队列中唤醒一个进程
Reading the file;
P(rc_mutex); //开始对rc共享变量的互斥访问
rc--; //一个读进程读完,读进程数减1
if rc=0 then V(write); //最后一个离开临界区的读进程需要判断是否有写进程
/ //需要进入临界区,若有,唤醒一个写进程进临界区V(rc_mutex); //结束对rc共享变量的互斥访问
}
void writer() /*写者进程*/
do{ P(read); //无读进程,写进程进入;有读进程,在read排队,其后
//到来的读进程排在该队列写者之后
P(write); //若有读进程在读,等待现有读进程读完才可写
Writeing the file;
V(write); //写进程完成;判断是否有读进程需要进入临界区,若有,
//唤醒一个读进程进临界区
V(read); //从read队列中唤醒一个进程
注意,该算法当第一个写者已经P(read)后,read变为0,来了N个读者,他们都停留在它的P(read)这一句。
那么会出现什么问题呢?此时,如果原来的写者完成了,紧接又来了一个写者,写者需要P(read)。
这个时候,由于N个读者都已经在这个写者之前P(read)了,所以这个写者需要排队排在这N个读者分别都得到P(read)后才能得到执行,这个就不是写者优先了,而是读者写者公平竞争。
(3)写者优先2。
为了保证写者相对于读者的优先,需要提高写者进程的优先级。
这里除增加一个排队信号量read,让读者和写者在读写之前都在此信号量上排队。
还需增加一个信号量write_first,来保证写者优先。
写者优先2的程序设计如下:
int rc, wc = 0; //用于读者,写者的计数
semaphore read, write = 1; //用于读进程和写进程的互斥信号量
semaphore rc_mutex, wc_mutex, write_first = 1;//用于读时、写时和写者优先的互斥
void reader(){ /*读者进程*/
while(1){
P(write_first); //用来保证写者优先。
若有写进程,第二个后的读者等待在这P(read); //若有写进程,第一个读进程等待;若无写进程,读进程进入P(rc_mutex); //开始对rc共享变量进行互斥访问
rc++; //更新读进程数
if (rc==1) P(write); //第一个读进程需要判断是否有写进程在临界区,若有,读进程
//等待,若无,阻塞写进程
V(rc_mutex); //结束对rc共享变量的互斥访问
V(read); //从read队列中唤醒一个进程
V(write_first);
doReading();
P(rc_mutex); //开始对rc共享变量进行互斥访问
rc--; //更新读进程数量
if (rc==0) V(write); //最后一个离开临界区的读进程需要判断是否有写进程
//需要进入临界区,若有,唤醒一个写进程进临界区V(rc_mutex); //结束对rc共享变量的互斥访问
}
}
void writer(){ /*写者进程*/
while(1){
P(wc_mutex); //开始对wc共享变量进行互斥访问
wct++; //更新写进程数
if (wc==1) P(read); //第一个写进程需要判断是否有读进程在临界区,若有,写进程
//阻塞,若无,阻塞新的读进程
V(wc_mutex); //结束对wc共享变量的互斥访问
P(write); //限制同一时刻只能有一个写进程进行写操作do writing();
V(write); //结束对写操作的限制
P(wc_mutex); //开始对wc的互斥访问
wc--; //更新写进程数量
if (wc==0) V(read); //最后一个离开临界区的写进程需要判断是否有读进程需要
//进入,若有,唤醒一个读进程进入临界区
V(wc_mutex); //结束对wc的互斥访问
}
}
这里write_first的设立是为了保证写者优先。
因为write_first的初值是1,在读进程,执行完P(write_first)后等在P(read)这一句的读者最多只有1个。
对于read信号量,每个读进程最开始都要申请一次,之后在真正做读操作前即让出,这使得写进程可以随时申请到read。
而写进程,只有第一个写进程需要申请read,之后就
一直占着不放了,直到所有写进程都完成后才让出。
等于只要有写进程提出申请就禁止读进程在read信号量上排队。
假设一个写进程正在写时,接着后续有n个读者正在等待,这时又有一个新的写者要写,比较一下写者优先1和写者优先2的情况:写者优先1新来的写者需要等待n+1次V(read)操作,而写者优先2新来的写者只需等待2次V(read)操作,变相提高了写进程的优先级。