-
2019-10-11 09:40:47
PV操作和读者写者问题是进程间相互作用的经典问题,今天我就用幼儿园都能看懂的大白话来把这个问题讲清楚。
我们都知道,现代操作系统中能同时运行多个程序,而每一个运行中的程序,就叫一个进程。这些进程有些是互不相干,各跑各的;而有些进程,它们可能会共享某些数据,需要相互协作才能正确运行,我们管这样的进程叫:相关进程。
举个简单的例子:流水线上的操作工A和B需要按顺序生产产品,A和B之间有一个加工容器,A负责将产品放进容器,然后B负责从容器取走产品,而这个容器一次只能容纳一个产品,如果A放的太快,就会放不下;如果B拿的太快,就会拿空。
车间主管一来,想了个办法,
对A说:A你每次放之前,就先问一声:“空了吗?”,要是空的呢,你就放,放好你就再喊一声:“满了!”;要是不空呢,你就先等着,等B拿走了,他会叫你的!
又对B说:B你每次拿之前,也问一声:“满了吗?”,要是满的呢,你就拿,拿走你也喊一声:“空了!”;要是不满呢,你就先等着,等A放好了,他会叫你的!
于是A和B便按主管说的,一起愉快的干了下去。
在这个问题中,为了确保正确的工作,A和B其实只关心各自的1个问题。A关心的是容器空了没有,空了我就放;而B关心的则是容器满了没有,满了我就拿。所以我们可以把A和B看做两个相关进程P1和P2,而他们各自关心的问题 "空了吗" 和 "满了吗" 分别用两个信号量empty和full来表示,让empty=1,让full=0,至于为什么一个是1一个是0我们后面再讲,先记着就好了。
先来看进程P1也就是放产品的进程,它的工作流是这样的:
- 问一声:"空了吗?"
- 如果是满的,就等着
- 如果是空的,就放产品
- 喊一声:"满了!"
写成伪代码就是:
while(true){ while( "空了吗?" 为 false){ //等着 } 放产品; 喊一声:"满了!"; }
我们可以看到,等待的部分,我们是用while来实现的。事实上,P操作就是用来帮我们干这个的。
用P操作修改之后的代码如下:
empty = 1; while(true){ P(empty); //问一声:"空了吗?";如果不空,就会在这等着 放产品; 喊一声:"满了!"; }
----------------------------------- 马上要考试了,先去看书了,下次再更,srysry 。2019/10/11 -----------------------------------
更多相关内容 -
通过研究经典的进程同步问题,采用“读写平等”的策略,用信号量 和 PV 操作实现对读者/写者问题的并发控制
2022-04-21 20:42:43(4)可读取样例数据(要求存放在外部文件中),进行读者/写者、进入内存时 间、读写时间的初始化; (5)要求将运行过程用可视化界面动态显示,可随时暂停,查看阅览室读者/ 写者数目、读者等待队列、写者等待队列... -
PV操作实现读者写者问题
2016-10-19 10:08:38实现PV操作解决读者写者问题(读者优先) -
操作系统 读者写者问题 pv操作
2010-05-26 10:58:23Wait(i,1,2,"第一个读者"); P(Sdoc);//锁 printf("--------------[%d]----------------缓冲区以被占用\n",i); Wait(i,1,2,".......取得缓冲区的控制权"); } V(Scnt);//读锁 V(Sr);//读写锁 Wait... -
读者写者问题PV操作实现(Java)
2018-12-19 10:26:58//读者写者问题 public class Test { public static void main(String[] args) { int wr, re; Scanner input = new Scanner(System.in); System.out.print("请输入写者数目:"); wr = inpu...import java.util.Scanner; //读者写者问题 public class Test { public static void main(String[] args) { int wr, re; Scanner input = new Scanner(System.in); System.out.print("请输入写者数目:"); wr = input.nextInt(); System.out.print("请输入读者数目:"); re = input.nextInt(); input.close(); // 实例化读者与写者对象 for (int i = 0; i < wr; i++) { new Thread(new Writer(), "写者线程r" + Integer.toString(i)) .start(); } for (int i = 0; i < re; i++) { new Thread(new Reader(), "读者线程r" + Integer.toString(i)) .start(); } } } //读者 class Reader implements Runnable { @Override public void run() { // TODO Auto-generated method stub Global.naps(); System.out.println(Thread.currentThread().getName() + " 等待..."); Global.R_mutex.P(); if (Global.RC == 0) { Global.RW_mutex.P(); } Global.RC++; Global.R_mutex.V(); System.out.println(Thread.currentThread().getName() + " 开始读..."); Global.naps(); System.out.println(Thread.currentThread().getName() + " 离开..."); Global.R_mutex.P(); Global.RC--; if (Global.RC == 0) { Global.RW_mutex.V(); } Global.R_mutex.V(); } } //写者 class Writer implements Runnable { @Override public void run() { // TODO Auto-generated method stub Global.naps(); System.out.println(Thread.currentThread().getName() + " 等待..."); Global.RW_mutex.P(); System.out.println(Thread.currentThread().getName() + " 开始写..."); Global.naps(); System.out.println(Thread.currentThread().getName() + " 离开..."); Global.RW_mutex.V(); } } //全局对象 class Global { public static Semaphore RW_mutex = new Semaphore(1); //写者与其他写者或读者互斥的访问共享数据 public static Semaphore R_mutex = new Semaphore(1); //读者互斥的访问读者计数器 public static int RC = 0; //对读者进行计数 //随机等待 public static void naps() { try { Thread.sleep((int) (2000 * Math.random())); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //信号量 class Semaphore { public int value; public Semaphore(int value) { super(); this.value = value; } //P操作 public synchronized final void P() { // TODO Auto-generated method stub value--; if(value < 0) { try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //V操作 public synchronized final void V() { // TODO Auto-generated method stub value++; if (value <= 0) { this.notify(); } } }
-
PV操作每日一题-读者写者问题
2021-11-08 20:34:55读者写者问题:读者优先以及写者优先。
一、问题描述
要求:
- 允许多个读者可以同时对文件进行执行读操作
- 只允许一个写者往文件中写信息
- 任一写者在完成写作操作之前不允许其他读者或写着进入缓冲区
- 写着执行写操作之前,应让已有的写者和读者全部退出
使用PV操作求解该问题
二、读者优先
int readercount=0; semaphore mutex=1; semaphore readermutex=1; reader() { while(1) { P(readermutex); if(readercount==0) { P(mutex); } readercount++; V(readermutex); 读文件; P(readermutex) readercount--; if(readercount==0) { V(mutex); } V(readercount); } } writer() { while(1) { P(mutex) 写文件; V(mutex); } }
三、写者优先
int readercount=0; semaphore mutex=1; semaphore writermutex=1; semaphore readermutex=1; reader() { while(1) { P(writermutex);//是否有写者在用缓冲区 P(readermutex); if(readercount==0) { P(mutex); } readercount++; V(readermutex); V(writermutex); 读文件; P(readermutex) readercount--; if(readercount==0) { V(mutex); } V(readercount); } } writer() { while(1) { P(writermutex);//是否有其他写者在用缓冲区 P(mutex) 写文件; V(mutex); V(writermutex); } }
-
PV操作系列--读者写者问题
2020-06-14 20:57:43(2) 一次只有一个写进程可以往文件中写; (3) 如果一个写进程正在进行操作,禁止任何读进程度文件。 读优先 一个读者试图进行读操作时,如果这时正有其他读者在进行操作,他可直接开始读操作,而不需要等待。 ...问题描述
有一个许多进程共享的数据区,这个数据区可以是一个文件或者主存的一块空间;有一些只读取这个数据区的进程(Reader)和一些只往数据区写数据的进程(Writer),此外还需要满足以下条件:
(1) 任意多个读进程可以同时读这个文件;
(2) 一次只有一个写进程可以往文件中写;
(3) 如果一个写进程正在进行操作,禁止任何读进程度文件。读优先
一个读者试图进行读操作时,如果这时正有其他读者在进行操作,他可直接开始读操作,而不需要等待。
readcount //读者计数器 var rwmutex, rmutex = 1, 1; int readcount = 0; cobegin procedure reader_i procedure Writer_j // i,j = 1,2,…. while true then while true then begin begin P(rmutex); P(rwmutex); 写更新; Readcount + +; V(rwmutex); if (readcount = = 1) end P(rwmutex); // rwmutex 大于0时,自动从此处运行 V(rmutex); 读数据; P(rmutex); Readcount - -; if (readcount = = 0) V(rwmutex); V(rmutex); end Coend
读优先–代码分析
读进程
- readcount 表示读进程数
- rmutex 是对于计数器readcount操作的互斥信号量,rwmutex表示是否允许写的信号量
- P(rmutex) 表示对每次有一个读者要进行读操作,要先对readcount 共享变量互斥操作,然后判断当前是否是第一名读者,如果是第一名读者,那么接下来将判断rwmutex信号量得出此时是否有作者在临界区(有的话,阻塞读进程;无,阻塞写进程)
- V(rmutex)表示结束对readcount共享信号量的互斥访问
- 读者读完后,又开始对readcount共享信号量的互斥访问,此时需要判断readcount是否为0,代表最后一个人离开读进程区,从而判断是否有写进程,if yes,唤醒其中一个写进程到临界区
写进程
- 如果有读进程,写进程阻塞
- 写进程完毕,判断是否有阻塞的读进程,if yes,唤醒其中一个读进程进入临界区。执行完V(rwmutex) 一方面相当于释放了写信号量,另一方面会自动唤醒读进程
写优先
1)多个读者可以同时进行读
2)写者必须互斥(只允许一个写操作,也不允许读写同时进行《rwmutex只有一份》)
3)写者优先于读者(一方面,一旦有写者(正在运行),则后续读者
必须等待,另一方面V(rwmutex)唤醒时 优先考虑写者,其次才是读者)
假设读者数是固定的
,算法如下:rwmutex:用于写者与其他读者/写者互斥的访问共享数据 rmutex:该信号量初始值设为10,表示最多允许10个读者进程同时进行读操作 var rwmutex, rmutex: semaphore := 1, 10; cobegin procedure reader_i procedure Writer_j begin begin // j = 1,2,…. P(rwmutex); P(rwmutex); P(rmutex); for (i = 1;i <= 10;i + +) P(rmutex); //读数据 V(rwmutex); //禁止新读者,并等待已进入的读者退出读进程 // 写更新; V(rmutex); for (i = 1;i <= 10;i + +) V(rmutex); end //恢复允许rmutex值为10,唤醒读进程 v(rwmutex) end Coend
写优先–代码分析
读进程
- 先检查P(rwmutex)确保:先有写操作时,读进程阻塞
- 先释放V(rwmutex) 一方面为了确保后续的读操作可以正常运行,另一方面此时如果有正在等待的写操作,优先唤醒写操作
- 读操作先运行就只有一种情况,就是必须在写操作之前申请rwmutex
写进程
- for (i = 1;i <= 10;i + +) P(rmutex); //一旦申请了写信号量,直接提前占用10个读信号量
- 写操作结束后,再通过循环释放读信号量
-
PV操作读者与写者问题,写优先
2013-10-14 21:25:59读者与写着问题中的,写者优先问题,解决了写无限等待问题 -
第二类读者写者问题(写者优先)的信号量及PV操作解决方案
2021-05-15 01:04:33(2)写者必须互斥(只允许一个写者写,也不能读者写者同时进行);(3)写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者)。定义读者与写者两个队列: ReadQ与WriterQ,初始值均为空;定义文件状态 ... -
【操作系统并发进程】信号量与PV操作例题讲解——读者写者问题
2021-12-15 23:27:37操作系统——信号量PV操作例题-读者写者问题 -
利用PV操作实现读者-写者问题(读者优先、写者优先)
2020-04-15 17:03:521.写者、读者互斥访问文件资源。 2.多个读者可以同时访问文件资源。 3.只允许一个写者访问文件资源。 .算法 Program reders writers; Var r_w_w:semaphore; mutex:semaphore; read_count:integer; Procedure ... -
《OS:PV操作 - 读者写者问题》
2021-07-05 18:29:52读者写者问题 背景:有多个读者,也有多个写者。要保证其互斥性。要求应用对应的PV操作实现。 定义: P,V操作均为原子操作 原子操作是在执行的过程中,要么全做,要么全不做,不可被CPU打断 P操作:简单说就是对一... -
C语言使用PV操作实现读者-写者问题
2020-04-26 22:50:55/*由于有了这处的判断,一来可以在读者来的时候写者不能进入阅览室 二来 就是写者在写的时候,这里P操作就会得到一个负数 这样自身就被阻塞,就完成了写者写的时候读者不能够进阅览室*/ if(readcount == 1) P(write... -
PV操作之读者写者问题:“南开大学和天津大学之前有一条弯曲的路”
2022-05-17 21:03:07PV操作之读者写者问题:"南开大学和天津大学之前有一条弯曲的路"原题描述解题思路PV操作题目变形解题思路PV操作思考与总结 原题描述 南开大学和天津大学之间有一条弯曲的路,同一方向每次只允许一辆自行车通过,中间... -
PV操作、生产者消费者问题、读者写者问题、睡眠理发师问题
2020-08-28 22:21:39P、V操作原语定义: P原语操作: 信号量减1,若此时信号仍然大于等于0,则进程继续执行...生产者消费者问题 伪代码描述 item B[k]; semphore empty; empty=k; semphore full; full=0; semphore mutex; metax=1; int in= -
PV操作:读者写者问题
2015-09-06 09:45:54package concurrent; import java.util.Date; import java.util.concurrent.Semaphore; public class WriterAndReader { public static void main(String[] args) { Semaphore resourceMutex = new Semaphore(1 -
操作系统读者写者问题(java用PV实现)
2021-11-22 11:57:17public class Main { public static void main(String[] args) { // 三个读者一个写者 Book book = new Book(); Reader reader1 = new Reader(book); Reader reader2 = new Reader(book); Reader reader3 = new ... -
操作系统PV操作及读者写者问题
2016-09-22 15:59:501、信号量: 2、P、V操作原语可描述为以下式子: 3、解释: 4、互斥模式原理: 5、同步模式原理: 6、读者写者问题: -
读者-写者问题.cpp
2020-03-26 16:32:26一个数据文件或者记录可被多个进程(或线程)共享。其中,有些进程(或线程)要求读;...所谓读者—写者问题是指保证一个Writer(或线程)进程必须与其他进程(或线程)互斥地访问共享对象的同步问题。 -
操作系统——读者-写者问题
2022-06-03 18:33:47有读者和写者两组并发进程,共享一个文件,当两个或两个以上的读进程...③任一写者在完成写操作之前不允许其他读者或写者工作; ④写者执行写操作前,应让已有的读者和写者全部退出。核心思想:设置计数器count用来记录 -
操作系统 | PV操作七大经典问题 生产者消费者 读者写者 哲学家进餐 理发师理发睡觉 和尚打水 吸烟者 吃水果
2021-12-30 13:53:35和尚打水问题(多生产者多消费者): 问题描述:某寺庙,有小和尚和老和尚若干,有一个水缸,由小和尚提水入缸供老和尚饮用。水缸可以容纳10桶水,水取自同一口井中,由于水井口窄,每次只能容纳一个水桶取水。水桶... -
四、操作系统——读者写者问题(详解)
2020-05-18 16:31:12写进程与写进程之间必须互斥的写入数据(因为如果两个写进程同时对共享数据中的区域A中的数据进行写操作的话,会导致数据错误覆盖的问题) 写进程与读进程之间必须互斥的访问共享数据(因为写进程与读进程如果同时... -
天津大学计算机科学与技术专业操作系统读者写者问题C++实现
2021-01-27 00:38:00本次实验要求使用信号量实现读者写者问题,其中包含读者优先与写者优先两种情况,实验目的:(1)运用信号量来实现读者写者问题(2)熟悉PV原语、信号量的运用。 本资源包括实验报告与实验代码 -
操作系统信号量PV经典问题:读者写者
2012-01-26 15:47:17操作系统信号量PV经典问题:读者写者,优先级是谁忘了,最经典的那个 C++编写 -
操作系统实验 读者写者问题
2011-12-03 23:12:51读者写者问题实验报告 有代码有流程图 使用PV原语做题 -
PV经典问题之读写者问题
2020-01-01 17:52:07问题描述 有一个许多进程共享的数据区,这个数据区可以是一个文件或者主存 的一块空间;有一些只读取这个数据区的进程(Reader)和一些只往数据区写数据的进 程...关系分析:由题⽬分析可知,读者和写者是互斥... -
操作系统课程设计 读者写者问题
2010-01-16 22:25:24在Windows环境下,采用系统调用,编程实现读者、写者问题,具体的要求为:一个数据集(如一个文件或记录)为多个并发进程所共享,其中一些进程只要求读该数据集的内容,这些进程称为“读者”,而另一些进程则要求... -
操作系统-读者写者问题(“写者优先“/读写公平)
2021-04-29 21:19:47* 读者优先 */ # include <stdio.h> # include <stdlib.h> # include <time.h> # include <sys/types.h> # include <pthread.h> # include <semaphore.h> # include <...