读者写者问题写者优先参考答案

合集下载

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

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

本科实验报告实验名称:操作系统原理实验(读者写者问题)课程名称:操作系统原理实验时间: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三、实验环境硬件设备:个人计算机。

采用“写优先”的策略演示“读者写者”问题(C_)

采用“写优先”的策略演示“读者写者”问题(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 信息分析:写者优先程序实现写者优先进行写,本程序主要功能包括增加读者写者,时间的显示,动态的显示读写过程,暂停继续。

操作系统PV操作经典例题与答案

操作系统PV操作经典例题与答案
离开;
P(mutex)
custNum--;
V(mutex)
V(wait)
}
理发师进程:
While{
P(mutex)
If(custNum ==0){
V(mutex)
P(Barber)
}else{
V(mutex)
理发
}
}
V(SM);
i = (i+1) %k;
};
Receive:
j =0;//标记取产品的缓存区位置
SM=0;//信号量,标记初始没有消息
ReadCount=0;//读进程计数器
Mutex =1;//读进程互斥信号量
SW=0; //信号量,读进程在此信号量等待
while (true) {
P(SM);
从Buffer[j]取消息;
V(W);
Else if(rw>0)
V(R)
rw--
V(mutex);
};
3.理发师睡觉问题
理发店里有一位理发师,一把理发椅和N把供等候理发的顾客坐的椅子
如果没有顾客,则理发师便在理发椅上睡觉。当一个顾客到来时,他必须先唤醒理发师
如果顾客到来时理发师正在理发,则如果有空椅子,可坐下来等;否则离开
Wait =0;表示等待顾客资源;
V(R)
rw--
}
V(mutex);

P(mutex);
rc--;
if (rc==0){
If(wc>0)V(w)
}
V(mutex);
};
写者:
while (true) {
P(mutex);
wc++;
if((wc >1)||(rc>0)){

读者写者问题

读者写者问题
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.读者—写者问题读者—写者问题(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++)

操作系统之读者与写者问题(C++)

代码的实现
1.开发语言,编译环境
Windows10,Visual Studio 2010,C语言
2.所要用到的头文件
#include <stdio.h> #include <Windows.h> #include <time.h>
代码的实现
3.定义变量及信号量
4.相关线程及方法体
代码的实现
主函数
解决问题的原理及方法
进程模拟和pv操作实现问题
1.采用多线程来模拟进程的并发执行, 创建线程用到的函数是 相关信号量的创建用到的函数是
2.
函数的功能是使线程自愿进入等待状态,
直到一个特定的内核对象变为已通知状态为止

函数的功能是释放互斥对象的控制权,可以理解
为使一个特定的内核对象变为已通知状态
以此来模拟pv操作
读者与写者问题
汇报人:18级计科师范1班李雪梅
目录
PART 01 问题描述 PART 02 解决问题的原理及方法 PART 03 代码实现 PART 04 实现效果
问题描述
读者与写者问题
有读者和写者两组并发进程,共享一个文件,当两个或以上的读 进程同时访问共享数据时不会产生副作用,但若某个写进程和其 他进程(读进程或写进程)同时访问共享数据时则可能导致数据 不一致的错误。因此要求: ①允许多个读者可以同时对文件执行读操作(同步); ②只允许一个写者往文件中写信息(互斥); ③任一写者在完成写操作之前不允许其他读者或写者工作(互斥) ④写者优先(外加条件)
解决问题的原理及方法
写者问题处理办法
1.由于写者与写者、写者与读者之间都是互斥关系,所以这 里可以设置一个写互斥信号量(write)来处理写者进程的 互斥问题

写者优先问题

写者优先问题

//eat .... signal(chopstick[i]); signal(chopstick[i+1]); ..... //think .... } while[TRUE]; 虽然上述解法可保证不会有两个相邻哲学家同时进餐,但却 有可能引起死锁。假如五位哲学家同时拿起左边的筷子,就 会使五个信号量chopstick均为0,;当他们试图去拿右边的筷 子时,都将因无筷子拿而无限等待,对于这样的死锁问题, 可采取以下几种解决方案:
哲学家进餐问题
问题是描述有五个哲学家共用一张圆桌,分别 坐在周围的五张椅子上,在圆桌上有五个碗和五只 筷子,他们的生活方式是交替的进行思考和进餐。 平时,一个哲学家进行思考,饥饿时候便试图取用 其左右最靠近他的筷子,只有在他拿到两只筷子时 才能进餐,进餐毕,放下筷子继续思考。
利用记录型信号量解决哲学家进餐问题
经分析可知,放在桌子上的筷子时临界资源,在一段时内只 允许一位哲学家使用,为了实现对筷子的互斥使用,可以用 一个信号量表示筷子,由这五个信号量构成信号量数组,其 描述如下: semaphore chopstick[5]={1,1,1,1,1} do{ wait(chopstick[i]); wait(chopstick至多只允许有四位哲学家同时去拿左边 的筷子,最终能保证至少有一位哲学家能够 进餐,并在用毕时能释放他用过的两只筷子, 从而使更多的哲学家能够进餐
semaphore chopstick[5]={1,1,1,1,1}; semaphore seat=4; void philosopher(int i) { while(true) { think(); wait(seat); //请求有板凳才可以 进餐
wait(chopstick[i]); //请求左手边的筷子 wait(chopstick[(i+1)%5]); //请求右手边的 筷子 eat(); signal(chopstick[(i+1)%5]); //释放右手边的 筷子 signal(chopstick[i]); //释放左手边的筷子 signal(seat); //退出释放信号量seat } }

操作系统例题汇总

操作系统例题汇总

1.2例题精选例1.1如何理解虚拟机的概念?解:一台仅靠由硬件组成的计算机一般被称为裸机,不易使用。

操作系统为用户使用计算机提供了许多服务,从而把一台难于使用的裸机改造成了功能更强大、使用更方便的计算机系统,这种计算机系统称为虚拟机。

所谓虚拟,是指把一个物理上的实体变为若干个逻辑上的对应物。

前者是实际存在的,而后者是虚的,只是用户的一种感觉。

在单CPU的计算机系统中能同时运行多道程序,好像每个程序都独享一个CPU,这就是虚拟。

在构造操作系统时,把操作系统分成若干层,每层完成特定的功能,从而形成一个虚拟机。

下层的虚拟机为上层的虚拟机提供服务,这样逐次扩充以完成操作系统的功能。

讨论“虚拟”的概念体现在操作系统的方方面面。

例如,虚拟存储器,使一台只有4MB 内存的计算机可以运行总容量远远超过4 MB的程序;虚拟外设,能够使多个用户同时访问该外设等。

例1.2什么是多道程序设计,它的主要优点是什么?解: 所谓多道程序设计是指把一个以上的程序存放在内存中,并且同时处于运行状态,这些程序共享CPU和其他计算机资源。

其主要优点是:(1)CPU的利用率高:在单道程序环境下,程序独占计算机资源,当程序等待I/O操作时CPU空闲,造成CPU资源的浪费。

在多道程序环境下,多个程序共享计算机资源,当某个程序等待I/O操作时,CPU可以执行其他程序,这大大地提高了CPU的利用率。

(2)设备利用率高:在多道程序环境下,内存和外设也由多个程序共享,无疑也会提高内存和外设的利用率。

(3)系统吞吐量大:在多道程序环境下,资源的利用率大幅度提高,减少了程序的等待时间,提高了系统的吞吐量。

讨论多道程序在计算机中并发地运行是现代计算机系统的重要特征。

早期的单道批处理系统与人工操作相比自动化程度大大提高,但系统中仍有较多的空闲资源,系统的性能较差。

多遭批处理系统虽有很多优点,但这种系统交互能力差,作业的平均周转时间长。

多道程序处理系统要解决的主要问题是,如何使多个程序合理、有序地共事处理机、内存、外设等资源。

读者写者问题_写者优先参考答案

读者写者问题_写者优先参考答案
V(Rmutex);
}
}
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,算法如下:}}现在回到【写者优先】优先问题【写者优先】在读者、写者问题中,如果总有读者进程进行读操作,会造成写者进程永远都不能进行写操作(读者优先),即所谓的写者饿死现象。

给出读者、写者问题的另一个解决方案:即保证当有一个写者进程想写时,不允许读者进程再进入,直到写者写完为止,即写者优先。

经典同步问题读者-写者问题

经典同步问题读者-写者问题

经典同步问题读者-写者问题读者-写者问题在读者-写者问题中,只对共享数据进⾏读取的进程为读者进程,修改共享数据的进程称为写者进程。

多个读者可同时读取共享数据⽽不会导致出现错误,但是任何时刻多个写者进程不能同时修改数据,写者进程和读者进程也不能同时访问共享数据。

读者-写者问题的解决策略有不同的倾向。

读者优先需要⽤到的共享变量:semaphore rw_mutex = 1; // 读者与写者互斥访问共享数据的互斥信号量semaphore mutex = 1; // 多个读者进程互斥修改当前读者进程数量的信号量int read_count = 0; // 系统当前读者进程数量写者进程结构do {wait(rw_mutex);.../* 修改共享数据 */...signal(rw_mutex);}while(true);读者进程结构do {wait(mutex); // 获取修改读者进程数量的互斥信号量,该操作在请求rw_mutex之前,防⽌出现死锁read_count++;if(read_count == 1) // 判断当前是否为第⼀个读者进程wait(rw_mutex); // 如果是就需要请求访问共享数据的互斥信号量signal(mutex); // read_count修改后释放信号量.../* 读取数据 */...wait(mutex); // 获取修改读者进程数量的互斥信号量read_count--;if(read_count == 0) // 判断当前进程是否为最后⼀个读者进程signal(rw_mutex); // 如果是则释放共享数据的互斥信号量,以允许写者进程操作共享数据signal(mutex);}while(true);读者优先有可能导致写者进程产⽣饥饿现象,当系统中不断出现读者进程时,写者进程始终⽆法进⼊临界区。

写者优先需要⽤到的共享变量:semaphore rw_mutex = 1; // 读者与写者互斥访问共享数据的互斥信号量semaphore r_mutex = 1; // 互斥修改当前读取⽂件的进程数semaphore w_mutex = 1; // 互斥修改当前修改⽂件的进程数semaphore enter_mutex = 1; // 获取申请访问⽂件的权限int read_count = 0; // 系统当前读者进程数量int write_count = 0; // 系统当前写者进程数量写者进程结构do {wait(w_mutex); // 新的写者进程进⼊,获取修改写者进程数量的权限write_count++;if(write_count == 1) // 判断当前是否为第⼀个写者进程wait(enter_mutex); // 阻断后续到达的读者进程signal(w_mutex);wait(rw_mutex); // 获取访问⽂件的权限,⽂件可能被其它写者进程占⽤,或者等待最后⼀个读者进程释放.../* 修改数据 */...wait(rw_mutex);wait(w_mutex);write_count--;if(write_count == 0) // 当所有写者进程都放弃使⽤⽂件时,运⾏读者进程申请访问⽂件signal(enter_mutex);signal(mutex);}while(true);读者进程结构do {wait(enter_mutex); // 获取申请访问⽂件的权限wait(r_mutex);read_count++;if(read_count == 1) // 判断当前是否为第⼀个读者进程wait(rw_mutex); // 占⽤⽂件signal(r_mutex);signal(enter_mutex);.../* 读取数据 */...wait(r_mutex);read_count--;if(read_count == 0)signal(rw_mutex);signal(r_mutex);}while(true);写者优先有可能导致读者进程产⽣饥饿现象,当系统中不断出现写者进程时,读者进程始终⽆法进⼊临界区。

读者-写者问题解答

读者-写者问题解答

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)读者优先的设计思想是读进程只要看到有其它读进程正在读,就可以继续进行读;写进程必须等待所有读进程都不读时才能写,即使写进程可能比一些读进程更早提出申请。

读者_写者问题的写者优先算法_符广全

读者_写者问题的写者优先算法_符广全

收稿日期:2003-03-13作者简介:符广全(1966)),男,山东费县人,临沂师范学院讲师.读者-写者问题的写者优先算法符广全(临沂师范学院计算机与信息科学系,山东临沂276005)摘 要:分析了操作系统中读者-写者这个经典进程同步问题,对读者优先的算法加以改进,探讨了用信号量实现的写者优先的算法.关键词:信号量;互斥;同步;算法中图分类号:TP316 文献标识码:A 文章编号:1009-6051(2003)06-0135-02并发是现代操作系统的重要特征,进程的并发大大提高了系统效率,但也带来了不确定因素.因此,并发系统中处理好进程的互斥与同步至关重要.信号量机制是解决进程互斥与同步问题的重要工具,其应用很多而又复杂、常易出错,是操作系统原理学习中的重点与难点之一.信号量(semaphore)是荷兰计算机科学家Dijkstra 在1965年提出的一个同步机制,对信号量只能进行Wai t(S)、Signal(S)两个原语操作.信号量及Wait(S)、Si gnal(S)原语描述如下:type Semaphore=recordvalue:integer; L:pointer to PCB; end Wai t(S):S.value:=S.value-1; if S.value<0then beginInsert(C ALLER,S.L); Block(CALLER); endSignal(S):S.value:=S.value+1;if S.value<=0 then beginRemove(S.L,id); Wakeup(id); end其中Insert 、Block 、Remove 、Wakeup 均是系统提供的过程.读者-写者问题是一个用信号量实现的经典进程同步问题.在系统中,一个数据集(如文件或记录)被几个并发进程共享,其中有些进程要求读数据集,而另一些进程要求写或修改数据集.我们把只要求读的进程称为/读者0,其他进程称为/写者0,把此类问题称为/读者-写者0问题(Reader -Writers Problem).在这类问题中,我们允许多个读者同时读此数据集,但绝不允许一个写者和其他进程(读者或写者)同时访问此数据集,因为这将违反Bernstein 条件,破坏数据的完整性、正确性.解决此问题的最简单的方法是:当没有写进程正在访问共享数据集时,读进程可以进入访问,否则必须等待.操作系统的教材中一般都给出了不考虑写者优先的共享算法.在这种算法中,只要有读者不断到来,写者就要持久地等待,直到所有的读者都读完且没有新的读者到来时写者才能写数据集,是一种读者优先的算法.在此我们要对此算法改进,探讨一种实现写者优先的算法.在这个算法中,我们要实现的目标是:首先,要让读者与写者之间以及写者与写者之间要互斥地访问数据集,其次,在无写进程到来时各读者可同时访问数据集;在读者和写者都等待时访问时写者优先.我们将用两个不同的互斥信号量分别实现读者与写者间的互斥及各写者进程间的互斥:以互斥信号量Wmutex 实现各写者间的互斥,用互斥信号量Rmutex 实现各读者与写者间的互斥;设置两个整型变量Wcount 和Rcount 分别记录等待的写者数和正在读的读者数,因Wcount 、Rcount 都是共享变量,因此还要设置两个互斥信号量Mut1和Mut2以实现进程对这两个变量的互斥访问.用信号量机制实现的写者优先的算法如下:Var Mut1,Mut2,Wmu tex ,Rmutex:Semaphore;Rcount,Wcount:integer;第25卷 第6期临沂师范学院学报2003年12月Vol.25No.6Journal of Linyi Teachers .College Dec.2003Mut1:=Mut2:=Wmu tex:=Rmutex:=1; Rcount:=Wcount:=0;beginparbeginwriteri:beginWai t(Mut1);Wcount:=Wcount+1;If Wcount=1then Wait(Rmutex);Signal(Mut1);Wai t(Wmutex);写数据集;Wai t(Mut1);Wcount:=Wcount-1;If Wcount=0then Si gnal(Rmutex);Signal(Wmutex);Signal(Mut1);end Readeri:beginWait(Mu t1);Signal(Mut1);Wait(Mu t2);Rcount:=Rcount+1;If Rcount=1then Wait(Rmutex);Signal(Mut2);读数据集;Wait(Mu t2);Rcount:=Rcount-1;If Rcount=0then Signal(Rmutex);Signal(Mut2);endcoendend正访问者等待者(a)W1R1R2W2W3R3(b)R1W1R2R3W2W3图1正访问者与等待者次序算法分析:假设有诸多读者R1、R2、R3,及诸多写者W1、W2、W3,都要访问数据集,对以下几种情况下的优先、互斥情况分析如下:(1)当写者先到达进入数据集访问,其后到达的次序如图1(a)所示.因第1个写者W1访问数据集前要执行Wait(Rmutex),第1个读者R1等待在信号量Rmutex上,其他的读者等待在信号量Mut2上;第2、第3写者W2、W3等待在信号量Wmutex上,Wcount=3.W1写完后唤醒写者W2、W3,写者得以先于读者访问;最后的写者访问完成后唤醒第1个读者R1,R1唤醒R2后去访问数据集,随后R3被唤醒,R2、R3可与R1同时访问数据集.(2)当读者正访问数据集,又有诸多读者到来而无写者到来时诸读者可共同读数据集.(3)当读者正访问数据集,又有诸多读者和写者到来时(如图1(b)所示),写者能优先于诸读者访问数据集.此时,第1个写者W1等待在信号量Rmutex上,这时的第二、第三读者R2、R3不能进入临界区与R1共同访问数据集,而是等待在信号量Mut1上,第2、第3写者W2、W3也等待在信号量Mut1上;一旦R1完成后,唤醒第1个写者W1去访问数据集,W1访问数据集之前它将唤醒R2,继而R3、W2、W3会被唤醒,R2会重新被阻塞在信号量Rmutex上,R3被阻塞在信号量Mut2上,W2、W3会重新被阻塞在信号量Wmutex上;第1个写者W1访问完后,先唤醒写者W2、W3,最后一个写者完成后才唤醒读者R2、R3,因此,写者W2、W3会优先于读者R2、R3去访问数据集.需要说明的是,进程并发是系统中常见而且复杂的问题,信号量在进程的互斥、同步等方面有广泛的应用,但实现的方法也并不仅限于信号量机制.用信号量解决读者-写者问题,实现写者优先的算法不止一种,在此仅作抛砖引玉,与读者共商榷.参考文献:[1]汤子瀛,杨成忠,哲凤屏.计算机操作系统[M].西安:电子科技大学出版社,1996.[2]屠祁,屠立德.操作系统基础.北京:清华大学出版社,2000.Writer Priority Calculation of the Reader-Writer ProblemFU Guang-quan(Department of Computer and Information Science,Linyi Teachers.College,Linyi Shandong276005,China)Abstract:Not only the classic process synchronization)))Reader-Writer Problem is analyzed,but also the method to improve Reader Priority calcula tion is provided in this article.At the sa me time,the realization of Writer Priority calculation by using semaphore is also discussed.Key words:semaphore;mutual repellency;synchronization;calculation136临沂师范学院学报第25卷。

读者写者问题中写者优先算法的实现

读者写者问题中写者优先算法的实现

读者写者问题中写者优先算法的实现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 启动线程最后,需要创建并启动多个读者线程和写者线程,以测试写者优先算法的实现。

操作系统 哲学家进餐问题 读者—写者问题

操作系统  哲学家进餐问题 读者—写者问题

读者—写者问题 8.3.4 读者 写者问题
有两组并发进程: 有两组并发进程 读者和写者,共享一组数据区 要求: 要求: 允许多个读者同时执行读操作 不允许读者、写者同时操作 不允许多个写者同时操作
12
读者—写者问题 8.3.4 读者 写者问题
读者--写者问题有两种类型: 读者 写者问题有两种类型: 写者问题有两种类型 第一类:读者优先- 第一类:读者优先-附解
①full:初值为 的信号量,表示缓冲区中已有的物品个数; 的信号量, :初值为0的信号量 表示缓冲区中已有的物品个数;
的信号量, ②empty:初值为 的信号量,表示缓冲区中可供使用的缓冲区数目; :初值为k的信号量 表示缓冲区中可供使用的缓冲区数目; 的信号量, ③mutex:初值为 的信号量,用于互斥使用缓冲区; :初值为1的信号量 用于互斥使用缓冲区;
Producer( ): while(TRUE) { 生产一个物品; 生产一个物品 P(empty); P(mutex);
/* 申请缓冲区里的空位 */ /* 进入临界区 */ /* 生产者进程程序 */
Consumer( ): { P(full); P(mutex);
/* 消费者进程程序 */
/* 缓冲区里有物品吗?*/ /* 进入临用数据时, 用数据时,其他读 者都不能使用该数 据,这不符合题目 要求。
8.3.4 读者—写者问题
(2) 判定是否是第 个读者 判定是否是第1个读者 希望在读者进程里, 希望在读者进程里,有一个办法能判定请求进入临界区 的是否是第1个读者。如果是第1个读者 个读者, 的是否是第 个读者。如果是第 个读者,就对信号量 wrt做 个读者 做 P操作, 以取得和写者的互斥 ; 如果是后继读者 , 就不再对 操作,以取得和写者的互斥;如果是后继读者, 操作 wrt 做P操作。 操作。 操作 为此, 它不是信号量)初值为 为此 , 设变量 first(它不是信号量 初值为 。 任何一个 它不是信号量 初值为0。 读者运行时,都先在first上加 ,然后判定它是否取值为 。 上加1,然后判定它是否取值为1。 读者运行时,都先在 上加 若是1,则做 否则不做。如图所示。 若是 ,则做P(wrt) ,否则不做。如图所示。

读者写者问题-写者优先参考答案

读者写者问题-写者优先参考答案

读者写者问题-写者优先参考答案【写者优先】在读者、写者问题中,如果总有读者进程进行读操作,会造成写者进程永远都不能进行写操作(读者优先),即所谓的写者饿死现象。

给出读者、写者问题的另一个解决方案:即保证当有一个写者进程想写时,不允许读者进程再进入,直到写者写完为止,即写者优先。

让我们先回顾读者写者问题[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,则迭代唤醒等待授权的读者;⏹读者到来,首先看授权标志,如果有授权标志,则继续,否则等待授权,即写者取消授权后,新来的读者不能申请缓冲区。

操作系统:读者-写者问题(C语言winapi)

操作系统:读者-写者问题(C语言winapi)

操作系统:读者-写者问题(C语⾔winapi)要求实现:1. 创建⼀个控制台进程,此进程包含n个线程。

⽤这n个线程来表⽰n个读者或写者。

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

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

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

2. 读-写互斥,即不能同时有⼀个线程在读,⽽另⼀个线程在写。

3. 即可以有⼀个或多个读者在读。

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

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

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

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

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

第⼀字段为⼀个正整数,表⽰线程序号。

第⼆字段表⽰相应线程⾓⾊,R表⽰读者,W表⽰写者。

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

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

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

下⾯是⼀个测试数据⽂件的例⼦:2 W 4 53 R 5 24 R 6 55 W 5.1 3注意:在创建数据⽂件时,由于涉及到⽂件格式问题,最好在记事本中⼿⼯逐个键⼊数据,⽽不要拷贝粘贴数据,否则,本⽰例程序运⾏时可能会出现不可预知的错误。

代码:⽤信号量实现,可先写出P/V操作的伪代码,再根据伪代码翻译C代码。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
增加Amutex互斥信号量,保护waitAuthCount、authFlag
增加同步信号量mutexAuth,表示等待授权的读者队列
【伪代码如下】
semaphore Wmutex=1, Rmutex=1 ,Amutex=1,mutexAuth=0;
int Rcount = 0;
int waitAuthCount=0;
{
P(Wmutex);
??;
write;/* 执行写操作 */
??;
P(Wmutex);
}
}
现在回到【写者优先】优先问题
【写者优先】在读者、写者问题中,如果总有读者进程进行读操作,会造成写者进程永远都不能进行写操作(读者优先),即所谓的写者饿死现象。给出读者、写者问题的另一个解决方案:即保证当有一个写者进程想写时,不允许读者进程再进入,直到写者写完为止,即写者优先。
V(Rmutex);
cout<<"读数据,线程ID:"<<GetCurrentThreadId()<<endl;
Sleep(500);/* 执行读操作 */
P(Rmutex);
Rcount = Rcount - 1;
if(Rcount == 0)
V(Wmutex);
V(Rmutex);
return1;
int authFlag=1;
void reader() /*读者进程*/
{
P(Amutex)....;
read; /* 执行读操作 */
......;
P(Rmutex);
Rcount = Rcount - 1;
if (Rcount == 0)
V(wmutex);
V(Rmutex);
}
}
void writer() /*写者进程*/
允许任意多的读进程同时读;
一次只允许一个写进程进行写操作;
如果有一个写进程正在进行写操作,禁止任何读进程进行读操作。
为了解决该问题,我们只需解决“写者与写者”和“写者与第一个读者”的互斥问题即
可,为此我们引入一个互斥信号量Wmutex,为了记录谁是第一个读者,我们用一个共享整
型变量Rcount 作一个计数器。而在解决问题的过程中,由于我们使用了共享变量Rcount,
}
V(Amutex);
return1;
};
intmain(intargc,char* argv[])
{
Wmutex=CreateSemaphore(NULL,1,1,NULL);
Rmutex=CreateSemaphore(NULL,1,1,NULL);
Authmutex=CreateSemaphore(NULL,1,1,NULL);
#defineV(S) ReleaseSemaphore(S,1,NULL)//定义Windows下的V操作
HANDLE Wmutex, Rmutex ,Authmutex,Amutex;
intRcount = 0;
intwaitAuthCount=0;
intauthFlag=1;
DWORD WINAPI reader(){
{
if(Rcount>0)
authFlag=0;
P(Wmutex);
......;
write; /* 执行写操作 */
......;
P(Wmutex);
P(Amutex)
while(waitAuthCount>0){
v(mutexAuth);
waitAuthCount--;
}
V(Amutex)
}
【vc++代码】
P(Amutex);
if(authFlag==0)
{
waitAuthCount++;
cout<<"等待授权,线程ID:"<<GetCurrentThreadId()<<endl;
P(Authmutex);
}
V(Amutex);
P(Rmutex);
if(Rcount == 0)
P(Wmutex);
Rcount = Rcount + 1;
else
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)reader,NULL,NULL,NULL);
}
Sleep(600000);
return0;
}
【运行结果】
参考文献
[1]计算机操作系统-郁红英-冯庚豹-人民邮电出版社
// by 西南大学计算机科学系周竹荣
//
#include""
#include""
#include""
#include<iostream>
#include<>
usingnamespacestd;
#defineP(S) WaitForSingleObject(S,INFINITE)//定义Windows下的P操作
Sleep(2000);/* 执行写操作 */
V(Wmutex);
cout<<"授权读,线程ID:"<<GetCurrentThreadId()<<endl;
P(Amutex);
authFlag=1;
while(waitAuthCount>0){
V(Authmutex);
waitAuthCount--;
【解题思路】在上面的读者写者问题基础上,做以下修改:
增加授权标志authFlag,当写者到来,发现有读者在读,则取消授权,然后等待缓冲区;
增加“等待授权计数器waitAuthCount”,写者离开时,如果waitAuthCount大于0,则迭代唤醒等待授权的读者;
读者到来,首先看授权标志,如果有授权标志,则继续,否则等待授权,即写者取消授权后,新来的读者不能申请缓冲区。
该变量又是一个临界资源,对于它的访问仍需要互斥进行,所以需要一个互斥信号量Rmutex,
算法如下:
semaphore Wmutex, Rmutex = 1;
int Rcount = 0;
void reader()/*读者进程*/
{
while (true)
{
P(Rmutex);
if (Rcount == 0) P(wmutex);
【写者优先】在读者、写者问题中,如果总有读者进程进行读操作,会造成写者进程永远都不能进行写操作(读者优先),即所谓的写者饿死现象。给出读者、写者问题的另一个解决方案:即保证当有一个写者进程想写时,不允许读者进程再进入,直到写者写完为止,即写者优先。
让我们先回顾读者写者问题[1]:
一个数据对象若被多个并发进程所共享,且其中一些进程只要求读该数据对象的内容,而另一些进程则要求写操作,对此,我们把只想读的进程称为“读者”,而把要求写的进程称为“写者”。在读者、写者问题中,任何时刻要求“写者”最多只允许有一个执行,而“读者”则允许有多个同时执行。因为多个“读者”的行为互不干扰,他们只是读数据,而不会改变数据对象的内容,而“写者”则不同,他们要改变数据对象的内容,如果他们同时操作,则数据对象的内容将会变得不可知。所以对共享资源的读写操作的限制条件是:
};
DWORD WINAPI writer(){
if(Rcount>0)
{
cout<<"取消授权,线程ID:"<<GetCurrentThreadId()<<endl;
authFlag=0;
}
P(Wmutex);
cout<<"写数据,线程ID:"<<GetCurrentThreadId()<<endl;
Amutex=CreateSemaphore(NULL,1,1,NULL);
while(1){
Sleep(100);
srand((unsigned)time(NULL));
intrC=rand()%1000;
Sleep(rC);
if( rC % 6==0)
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)writer,NULL,NULL,NULL);
Rcount = Rcount + 1;
V(Rmutex);
??;
read;/* 执行读操作 */
??;
P(Rmutex);
Rcount = Rcount - 1;
if (Rcount == 0) V(wmutex);
V(Rmutex);
}
}
void writer()/*写者进程*/
{
while (e)
相关文档
最新文档