java实现读者写者问题(写着优先)

合集下载

面向对象OS读者-写者问题

面向对象OS读者-写者问题

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

操作系统实验报告reader-writer

操作系统实验报告reader-writer

操作系统实验报告实验题目:ReaderWriter实验一.实验目的:1.通过编写和调试程序以加深对进程、线程管理方案的理解2.熟悉Windows多线程程序设计方法二.实验原理:读者-写者允许多个读者同时读一个数据对象,因为读文件不会使数据发生混乱,但不允许一个写者进程与其他读者进程或写者进程同时访问该数据对象。

文件是各个进程能互斥访问临界资源,读者进程和写者进程之间互斥。

在读者进程中,可以有多个读者读数据库,在读者进程的计数要互斥,避免发生错误,同时注意当第一个读者进程读时,一定要封锁写者进程。

当读者进程逐渐撤离时,要针对计数变量进行互斥操作,若当前为最后一个读者进程,读完后应唤醒写者进程。

所以应该分四类可能性:1.读者优先权比写者高,并且不用调配。

2.在一个读者已经占有文件的时候,全体读者的优先权才比写者高3.写者的优先权比读者的优先权高4.所有写者的和所有读者有相同的优先权三.实验代码:DataBaseBuffer:import java.awt.*;public class DataBaseBuffer extends Canvas{int[] readWantQ;int[] writerWantQ;String[] wantQ;int frameDelay = 1560;private int writerID;private int readerCount;private int wantCount;private int readerWantCount, writerWantCount;private int writerCount;private int wn, rn; // the number of readers and writersprivate int readTop, readBottom, writerTop, writerBottom;private int wantTop, wantBottom;private Font font;private FontMetrics fm;private boolean readLock = false;private boolean writeLock = false;public DataBaseBuffer( ){resize(500, 300);setBackground(Color.white);font = new Font("TimesRoman", Font.BOLD, 18);fm = getFontMetrics(font);}public void setSize(int readerN, int writerN){rn = readerN;wn = writerN;readTop = readBottom = writerTop = writerBottom = 0;readerCount = writerCount = readerWantCount = writerWantCount = 0;wantTop = wantBottom = 0;wantCount = 0;writerID = 0;readLock = false;writeLock = false;wantQ = new String[rn+wn];writerWantQ = new int[wn];readWantQ = new int[rn];repaint();}public synchronized void enterQueue(String s, int id){wantQ[wantTop] = s + id;wantTop ++;wantCount ++;repaint();}public synchronized void dequeue(String s, int id ){String str;str = s+id;while(!wantQ[0].equals(str)){try{ wait(); } catch(InterruptedException e) { } }for(int i = 0; i < (wantTop-1); i++){wantQ[i] = wantQ[i+1];}wantTop --;wantCount --;repaint();}public synchronized void changePosition(String s, int id) {String str;String tmp;int pos = 0; //to find the posting of 1st writer String wtr;wtr = s+id;while(!(wantQ[pos].equals(wtr))){pos++;}for(int i = 0; i < wantTop; i++){System.out.println(wantQ[i]);}str = wantQ[pos];for(int i = pos; i > 0; i--){wantQ[i] = wantQ[i-1];}wantQ[0] = str;repaint();for(int i = 0; i < wantTop; i++){System.out.println(wantQ[i]);}}public synchronized boolean hasWriterWant(){return (writerWantCount > 0);}public synchronized boolean hasReaderWant(){return (readerWantCount > 0);}public synchronized void acquireReadLock(ReaderWriterApplet applet, int id){readWantQ[readTop] = id; //nums is the index for readWantQreadTop = (readTop+1) % rn;readerWantCount ++;repaint();notifyAll();enterQueue("R", id);applet.r[id].status = 1; //want inapplet.mc.println(applet.r[id].status, "r", id);try{ applet.r[id].sleep(frameDelay);}catch(InterruptedException e) {}if(applet.writerPriority){while(hasWriterWant() || writeLock){applet.r[id].status = 3;applet.mc.println(applet.r[id].status, "r", id);try{ wait(); } catch(InterruptedException e) { } }//end of while loop}//end of if statementelse if(applet.readerPriority){while(readWantQ[readBottom] != id){try { wait(); } catch(InterruptedException e) {} }changePosition("R",id);}else{applet.r[id].status = 3;applet.mc.println(applet.r[id].status, "r", id);while(!wantQ[wantBottom].equals("R"+id)){try{ wait(); } catch(InterruptedException e) { } }}while(writeLock) //if there is any writer is writing {applet.r[id].status = 3;applet.mc.println(applet.r[id].status, "r", id);try{ wait(); } catch(InterruptedException e) { } }if(readLock == false){readLock = true;notifyAll();}readBottom = (readBottom+1) %rn;readerWantCount --;dequeue("R", id);readerCount ++;repaint();applet.r[id].status = 2;applet.mc.println(applet.r[id].status, "r", id);System.out.println("Reader "+id + "is reading");notifyAll();}public synchronized boolean hasReader(){return (readerCount > 0);}public synchronized void releaseReadLock(ReaderWriterApplet applet,int id){readerCount --;notifyAll();if(!hasReader()){readLock = false;notifyAll();applet.r[id].status = 4;applet.mc.println(applet.r[id].status, "r", id);}repaint();}public synchronized void acquireWriteLock(ReaderWriterApplet applet, int id){writerWantQ[writerTop] = id;writerTop=(writerTop+1)%wn;writerWantCount ++;notifyAll();repaint();enterQueue("W", id);applet.w[id].status = 1; //want inapplet.mc.println(applet.w[id].status, "w", id);try{ applet.w[id].sleep(frameDelay); }catch(InterruptedException e) {}if(applet.writerPriority){while(writerWantQ[writerBottom] != id){try{ wait(); } catch(InterruptedException e) { }}changePosition("W", id);while(readLock || writeLock){try{ wait(); } catch(InterruptedException e) { }}}else if(applet.readerPriority){while(!(wantQ[wantBottom].equals("W"+id)) || hasReaderWant() || readLock || writeLock){try{ wait(); } catch(InterruptedException e) { }}System.out.println("Writer "+ id + " move forward");}else{while(!(wantQ[wantBottom].equals("W"+id))){try{ wait(); } catch(InterruptedException e) { }}while(readLock || writeLock){try{ wait(); } catch(InterruptedException e) { }}}writeLock = true;System.out.println("Writer "+ id+ " Got the lock ******");notifyAll();dequeue("W", id);writerBottom = (writerBottom + 1)%wn;writerID = id;writerWantCount --;writerCount++;notifyAll();repaint();applet.w[id].status = 2;applet.mc.println(applet.w[id].status, "w", id);}public synchronized void releaseWriteLock(ReaderWriterApplet applet, int id){System.out.println("Writer " + id + " released the lock");writerCount --;writerID = 0;writeLock = false;notifyAll();repaint();}public void clear(){writerBottom = writerTop = 0;readBottom = readTop = 0;writerWantCount = 0;readerWantCount = 0;readerCount = 0;writerCount = 0;readLock = writeLock = false;writerWantQ = new int[wn];readWantQ = new int[rn];wantQ = new String[wn+rn];wantTop = wantBottom = 0;}public void paint(Graphics g){int xpos = 630;int ypos = 5;g.setFont(new Font("TimesRoman", Font.BOLD, 11));g.setColor(Color.green);g.draw3DRect(xpos, ypos, 10, 10, true);g.fillRect(xpos, ypos, 10, 10);g.drawString("Reading", xpos+15, ypos+10);g.setColor(Color.red);g.draw3DRect(xpos, ypos+14, 10, 10, true);g.fillRect(xpos, ypos+14, 10, 10);g.drawString("Writing", xpos+15, ypos+25);g.setColor(Color.blue);g.draw3DRect(xpos, ypos+28, 10, 10, true);g.fillRect(xpos, ypos+28, 10, 10);g.drawString("Empty", xpos+15, ypos+40);g.setFont(new Font("TimesRoman", Font.BOLD, 14));g.setColor(Color.blue);xpos = 40;ypos = 50;g.drawString("Waiting Queue", xpos-5, ypos-20);int i = wantBottom;for(int j = 0; j < wantCount; j++){if( wantQ[i].equals("W1") || wantQ[i].equals("W2")||wantQ[i].equals("W3")|| wantQ[i].equals("W4")||wantQ[i].equals("W5")){g.setColor(Color.red);g.drawString(wantQ[i], xpos+450-30*j, ypos-18);g.draw3DRect(xpos+445-30*j, ypos-35, 28, 28, true);}if( wantQ[i].equals("R1") || wantQ[i].equals("R2")||wantQ[i].equals("R3")|| wantQ[i].equals("R4")||wantQ[i].equals("R5")){g.setColor(Color.green);g.drawString(wantQ[i], xpos+450-30*j, ypos-18);g.draw3DRect(xpos+445-30*j, ypos-35, 28, 28, true);}i = (i+1) % (wn+rn);}if(readLock) g.setColor(Color.green);else if(writeLock) g.setColor(Color.red);else g.setColor(Color.blue);g.draw3DRect(xpos+250, ypos+20, 100, 100, true);g.fillRect(xpos+250, ypos+20, 100, 100);if(readLock){g.setColor(Color.black);g.drawString("Reading", xpos + 270, ypos+60);}else if(writeLock){g.setColor(Color.black);g.drawString("W " +Integer.toString(writerID), xpos + 280,ypos+45);g.drawString("Writing", xpos + 270, ypos+60);}}}MessageCanvas:import java.awt.*;class MessageCanvas extends Canvas{private Font font;private FontMetrics fm;private int[] writerStatus;private int[] readerStatus;private int msgHeight;private int msgWidth;private int pn, cn;private int frameDelay = 256;public MessageCanvas( ){resize(size().width, 50);setBackground(Color.green);font = new Font("TimesRoman", 1, 18);fm = getFontMetrics(font);msgHeight = fm.getHeight();}public void setMessage(int writerN, int readerN) {pn = writerN;cn = readerN;writerStatus = new int[pn+1];readerStatus = new int[cn+1];repaint();}void println(String s){msgWidth = fm.stringWidth(s);repaint();}void println(int s, String st, int id){if(st.equals("w"))writerStatus[id] = s;elsereaderStatus[id] = s;repaint();}void println(int s, int number, String st, int id){if(st.equals("w")){writerStatus[id] = s;}else{readerStatus[id] = s;}repaint();}public void paint(Graphics g){g.setFont(font);int xpos = 60;int ypos = 40;g.drawString("Status of Readers: ", 60, 20);g.drawString("Status of Writers: ", 360, 20);g.setFont(new Font("TimesRoman", 1, 14));for(int i=1; i<=cn;i++){g.setColor(Color.black);g.drawString("R" + i, xpos, ypos+(15*i+10*(i-1)));if(readerStatus[i] == 0){g.setColor(Color.yellow);g.fillOval(xpos+60, ypos+(2*i+22*(i-1)), 18, 18);g.drawString("Sleeping ...", xpos+120, ypos+(15*i + 10*(i-1)));}else if (readerStatus[i] == 1){g.setColor(Color.gray);g.fillOval(xpos+60, ypos+(2*i+22*(i-1)), 18, 18);g.drawString("Want to read", xpos+120, ypos+(15*i + 10*(i-1)));}else if (readerStatus[i] == 3){g.setColor(Color.gray);g.fillOval(xpos+60, ypos+(2*i+22*(i-1)), 18, 18);g.drawString("Waiting in the queue", xpos+120, ypos+(15*i + 10*(i-1)));}else if (readerStatus[i] == 2){g.setColor(Color.blue);g.fillOval(xpos+60, ypos+(2*i+22*(i-1)), 18, 18);g.drawString("Reading...", xpos+120, ypos+(15*i + 10*(i-1)));}}xpos = 360;ypos = 40;for(int i=1; i<=pn; i++){g.setColor(Color.black);g.drawString("W" + i, xpos, ypos+(15*i+10*(i-1)));if(writerStatus[i] == 0){g.setColor(Color.yellow);g.fillOval(xpos+60, ypos+(2*i+22*(i-1)), 18, 18);g.drawString("Sleeping ...", xpos+120, ypos+(15*i + 10*(i-1)));}else if (writerStatus[i] == 1){g.setColor(Color.gray);g.fillOval(xpos+60, ypos+(2*i+22*(i-1)), 18, 18);g.drawString("Waiting in the queue", xpos+120, ypos+(15*i + 10*(i-1)));}else if (writerStatus[i] == 2){g.setColor(Color.blue);g.fillOval(xpos+60, ypos+(2*i+22*(i-1)), 18, 18);g.drawString("Writing ...", xpos+120, ypos+(15*i + 10*(i-1)));}}}}Reader:public class Reader extends Thread{private DataBaseBuffer buffer;private ReaderWriterApplet tapplet;private int cid;int delay = 6500;int status = 0;public Reader(ReaderWriterApplet applet, DataBaseBuffer db, int id){ buffer = db;tapplet = applet;cid = id;}public void run(){while(true){try{status = 0;tapplet.mc.println(status, "r", cid);sleep((int) (Math.random()*delay));buffer.acquireReadLock(tapplet, cid);sleep((int) (Math.random()*delay));buffer.releaseReadLock(tapplet, cid);} catch(InterruptedException e){System.err.println("Reader Execption " + e.toString());}}}}ReaderWriterApplet:import java.awt.*;import java.awt.event.*;import java.util.*;import java.applet.Applet;import ng.*;public class ReaderWriterApplet extends Applet{private ReaderWriterApplet applet = this;private DataBaseBuffer myBuffer;private int buffersize;private Button fastButton, slowButton, stopButton, startButton, pauseButton, continueButton;private Button stopReaderButton, stopWriterButton;private Panel buttonPanel, priorityPanel, namePanel;private Choice priority, reader, writer;private Thread at;private int readerN = 1;private int writerN = 1;boolean readerPriority = false;boolean writerPriority = false;boolean samePriority = true; //default priority of readers and writers MessageCanvas mc;Reader[] r;Writer[] w;synchronized void startPushed() {notify();}synchronized void stopPushed() {notify();}public void init() {myBuffer = new DataBaseBuffer();mc = new MessageCanvas();resize(800, 600);setLayout(new GridLayout(3, 1));add(myBuffer);add(mc);buttonPanel = new Panel();priorityPanel = new Panel();namePanel = new Panel();Panel bPanel = new Panel(); // to hold all buttons and the labels bPanel.setFont(new Font("TimesRoman", Font.BOLD, 14));bPanel.setLayout(new GridLayout(3, 1));buttonPanel.add(startButton = new Button("START"));buttonPanel.add(stopButton = new Button("STOP"));buttonPanel.add(pauseButton = new Button("PAUSE"));buttonPanel.add(continueButton = new Button("CONTINUE"));buttonPanel.add(fastButton = new Button("FASTER"));buttonPanel.add(slowButton = new Button("SLOWER"));Panel choicePanel = new Panel(); //to hold all the choice boxespriority = new Choice();priority.addItem("Same Priority");priority.addItem("Writers Have Priority");priority.addItem("Readers Have Priority");priority.select("Same Priority");Label priorityLabel = new Label("Priority", 2);priorityLabel.setBackground(Color.lightGray);priorityPanel.add(priorityLabel);priorityPanel.add(priority);choicePanel.add(priorityPanel);reader = new Choice();for(int i = 0; i <=5; i++){reader.addItem(Integer.toString(i));}reader.select("1");Label readerLabel = new Label("Number of Readers", 2);readerLabel.setBackground(Color.lightGray);Panel readerPanel = new Panel();readerPanel.add(readerLabel);readerPanel.add(reader);writer = new Choice();for(int i = 0; i<=5; i++){writer.addItem(Integer.toString(i));}writer.select("1");Label writerLabel = new Label("Number of Writers", 2);writerLabel.setBackground(Color.lightGray);Panel writerPanel = new Panel();writerPanel.add(writerLabel);writerPanel.add(writer);Label nameLabel = new Label("Readers/Writers Animation");nameLabel.setFont(new Font("TimesRoman", Font.BOLD, 18));nameLabel.setForeground(Color.blue);namePanel.add(nameLabel);choicePanel.add(readerPanel);choicePanel.add(writerPanel);bPanel.add(choicePanel);bPanel.add(buttonPanel);bPanel.add(namePanel);add(bPanel);}public boolean action(Event evt, Object arg){if(evt.target == priority){if(arg.equals("Writers Have Priority")){writerPriority = true;readerPriority = false;samePriority = false;}else if(arg.equals("Readers Have Priority")) {readerPriority = true;writerPriority = false;samePriority = false;}else{readerPriority = false;writerPriority = false;samePriority = false;}return true;}else if(evt.target == reader){readerN = Integer.parseInt(arg.toString());return true;}else if(evt.target == writer){writerN = Integer.parseInt(arg.toString());return true;}else if(arg.equals("FASTER")){int newDelay;if(readerN != 0) newDelay = r[1].delay;else newDelay = w[1].delay;newDelay /= 2;newDelay = newDelay < 100 ? 100: newDelay;for(int i = 1; i <= readerN; i++){r[i].delay = newDelay;for(int i = 1; i <= writerN; i++){w[i].delay = newDelay;}return true;}else if(arg.equals("SLOWER")){int newDelay;if(readerN !=0) newDelay = w[1].delay;else newDelay = r[1].delay;newDelay *= 2;for(int i = 1; i <= readerN; i++){r[i].delay = newDelay;}for(int i = 1; i <= writerN; i++){w[i].delay = newDelay;}return true;}else if(arg.equals("PAUSE")){for(int i = 1; i <= readerN; i++){r[i].suspend();}for(int i = 1; i <= writerN; i++){w[i].suspend();}fastButton.setEnabled(false);slowButton.setEnabled(false);return true;}else if(arg.equals("CONTINUE")){for(int i = 1; i <= readerN; i++){if(r[i].isAlive()) r[i].resume();}for(int i = 1; i <= writerN; i++)if(w[i].isAlive()) w[i].resume();}fastButton.setEnabled(true);slowButton.setEnabled(true);return true;}else if(arg.equals("START")){r = new Reader[readerN+1]; //Reader[0] is a dummy slotw = new Writer[writerN+1];System.out.println("readers: "+readerN+" writers: " + writerN);mc.setMessage(writerN, readerN);myBuffer.setSize(readerN, writerN);for(int i = 1; i <= readerN; i++){r[i] = new Reader(applet, myBuffer, i);}for(int i = 1; i <= writerN; i++){w[i] = new Writer(applet, myBuffer, i);}for(int i = 1; i <= writerN; i++){w[i].start();}for(int i = 1; i <= readerN; i++){r[i].start();}fastButton.setEnabled(true);slowButton.setEnabled(true);startButton.setEnabled(false);reader.setEnabled(false);writer.setEnabled(false);priority.setEnabled(false);applet.startPushed();return true;}else if(arg.equals("STOP")){for(int i = 1; i <= readerN; i++){if(r[i].isAlive())r[i].stop();r[i] = null;}for(int i = 1; i <= writerN; i++){if(w[i].isAlive())w[i].stop();w[i] = null;}applet.stopPushed();startButton.setEnabled(true);fastButton.setEnabled(true);slowButton.setEnabled(true);reader.setEnabled(true);writer.setEnabled(true);priority.setEnabled(true);if(at != null) at.stop();at = null;return true;}else{ return false;}}}Writer:public class Writer extends Thread{private DataBaseBuffer buffer;private ReaderWriterApplet tapplet;private int id;int delay = 6500;int status = 0;public Writer(ReaderWriterApplet applet, DataBaseBuffer db, int id){ buffer = db;tapplet = applet;this.id = id;}public void run(){while(true){try{status = 0;tapplet.mc.println(status, "w", id);sleep((int)(Math.random()*delay));buffer.acquireWriteLock(tapplet, id);sleep((int) (Math.random()*delay));buffer.releaseWriteLock(tapplet, id);} catch(InterruptedException e){System.err.println("Execption " + e.toString());}}}}四.实验结果:运行如下:。

读者-写者问题的实现

读者-写者问题的实现

目录摘要 (1)1.设计思想 (2)2.各模块的伪码算法 (3)3. 函数关系调用图 (5)4.程序测试结果 (6)设计总结 (9)参考文献 (10)致谢 (11)摘要本设计的读者写者问题,是指一些进程共享一个数据区。

数据区可以使一个文件、一块内存空间或者一组寄存器。

Reader进程只能读数据区中的数据,而writer进程必须与其他进程互斥地访问共享对象的同步问题。

读者写者问题可以这样的描述, 有一群写者和一群读者, 写者在写同一本书, 读者也在读这本书, 多个读者可以同时读这本书。

但是,只能有一个写者在写书, 并且,读者必写者优先,也就是说,读者和写者同时提出请求时,读者优先。

当读者提出请求时需要有一个互斥操作, 另外, 需要有一个信号量S来确定当前是否可操作。

本设计方案就是通过利用记录型信号量对读者写者问题的解决过程进行模拟演示,形象地阐述记录型信号量机制的工作原理。

关键词:共享对象,互斥,同步,信号量1.设计思想本设计借助C语言实现进程同步和互斥的经典问题--读者写者问题,用高级语言编写和调试一个进程同步程序,以加深对进程同步机制的理解。

通过用C 语言模拟进程同步实现,加深理解有关进程同步和互斥机制的概念及P、V操作的应用。

学生通过该题目的设计过程,掌握读者、写者问题的原理、软件开发方法并提高解决实际问题的能力。

在 Windows环境下,创建一个包含n个线程的控制台进程。

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

程来表示 n 个读者或写者。

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

将所有的读者和所有的写者分别放进两个等待队列中,当读允许时就让读者队列释放一个或多个读者,当写允许时,释放第一个写者操作。

读者-写者的读写限制(包括读者优先和写者优先)1)写-写互斥,即不能有两个写者同时进行写操作;2)读-写互斥,即不能同时有一个读者在读,同时却有一个写者在写;3)读读允许,即可以有 2 个以上的读者同时读;4)读者优先附加条件:如果一个读者申请进行读操作,同时又有一个读操作正在进行读操作,则该读者可以直接开始读操作;5)写者优先附加条件:如果一个读者申请进行读操作时已经有一个写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。

读者写者问题

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

写优先”策略的“读者-写者”问题

写优先”策略的“读者-写者”问题

采用“写优先”策略的“读者-写者”问题学院计算机科学与技术专业计算机科学与技术学号学生姓名指导教师姓名2014-3-11目录一、设计目的与内容 ................................................ 错误!未定义书签。

(1 )、课程设计的目的 (1)(2 ) 、课程设计的内容 (1)(3 ) 、课程设计的要求 (1)二、算法的基本思想 ................................................ 错误!未定义书签。

三、模块流程图......................................................... 错误!未定义书签。

四、测试结果............................................................. 错误!未定义书签。

五、结论..................................................................... 错误!未定义书签。

六、源程序................................................................. 错误!未定义书签。

一、设计目的与内容(1)课程设计的目的:操作系统课程设计是计算机专业重要的教学环节,它为学生提供了一个既动手又动脑,将课本上的理论知识和实际有机的结合起来,独立分析和解决问题的机会。

●进一步巩固和复习操作系统的基础知识。

●培养学生结构化程序、模块化程序设计的方法和能力。

●提高学生调试程序的技巧和软件设计的能力。

●提高学生分析问题、解决问题以及综合利用C语言进行程序设计的能力。

(2) 课程设计的内容:用高级语言编写和调试一个采用“写优先”策略的“读者—写者”问题的模拟程序。

(3) 课程设计的要求:1.读者与写者至少包括ID、进入内存时间、读写时间三项内容,可在界面上进行输入。

读者写者问题写者优先参考答案完整版

读者写者问题写者优先参考答案完整版

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

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

让我们先回顾读者写者问题[1]:一个数据对象若被多个并发进程所共享,且其中一些进程只要求读该数据对象的内容,而另一些进程则要求写操作,对此,我们把只想读的进程称为“读者”,而把要求写的进程称为“写者”。

在读者、写者问题中,任何时刻要求“写者”最多只允许有一个执行,而“读者”则允许有多个同时执行。

因为多个“读者”的行为互不干扰,他们只是读数据,而不会改变数据对象的内容,而“写者”则不同,他们要改变数据对象的内容,如果他们同时操作,则数据对象的内容将会变得不可知。

所以对共享资源的读写操作的限制条件是:允许任意多的读进程同时读;一次只允许一个写进程进行写操作;如果有一个写进程正在进行写操作,禁止任何读进程进行读操作。

为了解决该问题,我们只需解决“写者与写者”和“写者与第一个读者”的互斥问题即可,为此我们引入一个互斥信号量Wmutex,为了记录谁是第一个读者,我们用一个共享整型变量Rcount 作一个计数器。

而在解决问题的过程中,由于我们使用了共享变量Rcount,该变量又是一个临界资源,对于它的访问仍需要互斥进行,所以需要一个互斥信号量Rmutex,算法如下:}}现在回到【写者优先】优先问题【写者优先】在读者、写者问题中,如果总有读者进程进行读操作,会造成写者进程永远都不能进行写操作(读者优先),即所谓的写者饿死现象。

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

“读者-写者”问题的Java实现

“读者-写者”问题的Java实现
步 互 斥 问 题 , 过 对 该 问 题 的 研 究 可 以 较 深 入 理 解 通
并 掌握 临 界 区 的概 念 并 应 用 于 解 决 实 际 问题 。 本 文 给 出 应 用 Jv aa语 言 设 计 一 种 针 对 “ 者 一 读 写 者” 问题 的一 个解 决 方 案 , 以帮 助对 临界 区 的理 解 及 临界 区程 序设 计 。
个 支 持 多 线 程 的 服 务 器 中 , 客 户 提 供 两 种 为
服 务 : 种 是 向 服 务 器 的共 享 缓 冲 区 中 写 入 数 据 的 一
“ ” 写 服务 ; 一 种 是 由服 务 器 的共 享 数 据 区 中 读 另
取 数 据 的“ ” 读 服务 。有 任 意 多 个 客户 向服 务 器 提 出 “ ” “ ” 申请 服务 。当 “ ” 务操 作 时 , 读 或 写 的
摘 要 :在 多道 程 序 设 计 中 , 源 的 共 享 以 及 共 享 资 源 的 资 互斥 访 问 的特 性 需 要 多 个 进 程 或 同 一 进 程 中 的 多 个 线 程
对 某 共 享 资 源 进 行 同 步 互 斥 访 问。 “ 者 一 者 ”问题 是 现 读 写 代 操作 系 统 中 经 典 的 同 步 互 斥 问 题 , 客 户/ 务 器 为 代 以 服 表 的 多进 ( ) 通 信 系 统 应 用 皆可 以抽 象 为 该 模 型 的 不 线 程 同 形 式 。提 出一 种 针 对 “ 者 ~写 者 ”问题 的 一 个 解 决 方 读 案 , 应 用 Jv 并 a a语 言 加 以实 现 。 关 键 词 :临界 资源 ; 同步 ; 互斥 ;a a 言 Jv 语 中 图分 类 号 : P3 1 6 T 0 .
1 写 一 操 作 互 斥 , 不 能 同 时 为 两 个 不 同 的 ) 写 即

java实现读者写者问题(写着优先)

java实现读者写者问题(写着优先)

实验一实验报告学号:20092128 姓名:徐卓远实验序号:1实验名称:用信号量来实现读者-写者问题实验目的:理解进程同步与互斥的概念,掌握用信号量来实现进程的同步与互斥。

实验设计及实现:为了实现读者和写者的读写过程,将每个读者和每个写者作为了一个单独的线程,所以设置了两个类,一个是读者类Reader,一个是写者类Writer.以读者类为例:一个读者的动作过程为由睡眠->等待->开始读->结束读->睡眠的一个循环过程,而一个写者的动作过程也为此.读者调用方法napping()进行等待,调用startRead()方法开始读,最后在调用endReading()方法结束读入,释放运行空间.写者同读者.但是为了实现读者写者之间的写-写互斥,读-写互斥,读-读允许,需要另外一个类Database,类中分别用关于读者的方法和写者的方法来控制读写之间的这种关系.首先要实现睡眠的方法napping(),读者和写者在睡眠过程都应该是一样的,只是他们睡眠的时间不同,所以只需写出一个方法:public static void napping() {int sleepTime = (int) (NAP_TIME * Math.random()); try {Thread.sleep(sleepTime * 1000);} catch (Exception e) {e.printStackTrace();}}在方法中,控制线程休眠随机的时间,由于每个读者或写者都是一个线程,而每个读者或写者他们工作休眠的时间都不一定相同,他们请求工作的时间也不一定相同,所以取了随机时间其次设置了读者的两个方法,开始读和结束读,由于这只是个模拟读写问题,所以只需要知道结果就行,就不用显示出他是怎么读的.在开始读中,当有写者在写时,读者需要等待wait(),在没有人在工作时,如果有写者和读者同时请求,那么就让写者先进,这是写者优先.所以这就归纳于一种情况, 当读者布尔变量dbReading为FALSE时,如果有需要工作的写者,那么读者就等待.当读者请求读入后,计数有多少读者需要工作的变量readerCount +1,如果这是第一个进入工作的读者就需要将显示是否有读者在工作的读者布尔变量变为TRUE.public synchronized int startRead() {if (dbReading == false) {while (writerCount > 0) {try {System.out.println("reader is waiting");wait();} catch (Exception e) {System.out.println(e.toString());e.printStackTrace();}}}++readerCount;if (readerCount == 1) {dbReading = true;}return readerCount;}读结束时,计数需要读的读者数-1,然后释放出空间给需要工作的人.public synchronized int endReading() {--readerCount;if (readerCount == 0) {dbReading = false;}notifyAll();//释放出空间System.out.println("one reader is done, reading.Count=" + readerCount);return readerCount;}第三,编写关于写者的开始写和结束写方法,在开始写方法中,首先要将计数需要写的变量writerCount+1,写者如果有读者或者有写者正在工作,那么就等待,如果没有就直接进入写,然后表示是否有写者在写的布尔变量dbWriting变为TRUEpublic synchronized void startWriting() {//控制写者开始进入写++writerCount;while (dbReading == true || dbWriting == true) {try {System.out.println("Writer is waiting");wait();} catch (Exception e) {System.out.println(e.toString());}}dbWriting = true;}结束时只需将writerCount-1和dbWriting为FALSE,然后释放出空间.public synchronized void endWriting() {//控制写者结束写入--writerCount;dbWriting = false;System.out.println("one writer is done, writing.Count=" + writerCount);notifyAll();}源代码及程序流程图主类:package rw;/**** @author xzy*/public class Main {public static void main(String[] args) {Database db=new Database();//实例化类Database为dbReader r1=new Reader(1,db);//实例化类Reader为r1Reader r2=new Reader(2,db);Reader r3=new Reader(3,db);Reader r4=new Reader(4,db);Writer w1=new Writer(1,db);//实例化类Writer为w1Writer w2=new Writer(2,db);r1.start();//读者1调用start()方法开始进入读写这个模拟环境中r2.start();r3.start();w1.start();r4.start();w2.start();}}Database类:package rw;/**** @author xzy*/public class Database {private static final int NAP_TIME = 5;private int readerCount;//变量计数需要读的读者private int writerCount;//变量计数需要写的写者private boolean dbReading;//表示是否有读者在读private boolean dbWriting;//表示是否有写者在写public Database() {readerCount = 0;//变量计数需要读的读者为0writerCount = 0;//变量计数需要写的写者为0dbReading = false;//表示没有读者正在读入dbWriting = false;//表示没有写者正在写入}public static void napping() {//控制睡眠的时间int sleepTime = (int) (NAP_TIME * Math.random());//睡眠时间随机try {Thread.sleep(sleepTime * 1000);} catch (Exception e) {e.printStackTrace();}}public synchronized int startRead() {//控制读者开始读if (dbReading == false) {//当没有读者在读时while (writerCount > 0) {//当有写者想写时try {System.out.println("reader is waiting");wait();//等待} catch (Exception e) {System.out.println(e.toString());e.printStackTrace();}}}++readerCount;//请求读入的读者数加一if (readerCount == 1) {dbReading = true;//标明有读者正在读}return readerCount;}public synchronized int endReading() {//控制读者结束读入--readerCount;if (readerCount == 0) {dbReading = false;}notifyAll();//释放出空间给其他的线程System.out.println("one reader is done, reading. Count=" + readerCount);return readerCount;}public synchronized void startWriting() {//控制写者开始进入写++writerCount;//想写的写者数加一while (dbReading == true || dbWriting == true) {//当有读者在读或者有写者在写时都得等待try {System.out.println("Writer is waiting");wait();} catch (Exception e) {System.out.println(e.toString());}}dbWriting = true;}public synchronized void endWriting() {//控制写者结束写入--writerCount;dbWriting = false;System.out.println("one writer is done, writing. Count=" + writerCount);notifyAll();}}Reader类:package rw;/**** @author xzy*/public class Reader extends Thread {private Database server;//设置一个Database变量用来控制该读者private int readerNum;//设置该读者的标志public Reader(int r, Database db) {readerNum = r;server = db;}@Overridepublic void run() {int c;while (true) {System.out.println("reader " + readerNum + " is sleeping");Database.napping();//表明读者正在睡眠状态System.out.println("reader " + readerNum + " wants to read");c = server.startRead();//读者开始请求读入工作System.out.println("reader " + readerNum + " is reading. Count=" + c);Database.napping();//读者处于工作阶段c = server.endReading();//读者结束工作System.out.println("It is reader " + readerNum + " who has done reading according to count=" + c);}}}Writer类:package rw;/**** @author xzy*/public class Writer extends Thread {private Database server;//设置一个Database变量用来控制该写者private int writerNum;//设置该写者的标志public Writer(int w, Database db) {writerNum = w;server = db;@Overridepublic void run() {while (true) {System.out.println("Writer " + writerNum + " is sleeping");Database.napping();//表明写者正在睡眠状态System.out.println("Writer " + writerNum + " wants to write");server.startWriting();//写者开始请求读入工作System.out.println("Writer " + writerNum + " is writing");Database.napping();//写者处于工作阶段server.endWriting();//写者结束工作System.out.println("It is Writer " + writerNum + " who has done writing .");}}}写者:实验当堂所要完成的事情:解决编译和运行出现的问题.编译过程中出现的问题及其相应解决:1.一个读者或者写者工作完时无法释放出空间给其他人解决:用了notifyall()方法,最开始只知道notify()方法,要释放出空间给所有人平等使用权利那么就必须用notifyall()方法.运行过程中出现的问题及其相应解决:1.实现了写者优先但是没有实现读读允许解决:加了一个判断if,如果没有读者读才做出写者优先的判断.实验总结通过本次实验,我对读者-写者的过程有了清楚的认识,对互斥和同步有了更深一步的了解,在最开始的实验中,我没有正确理解好写者优先,当有写者等待时,读者就不能进入了,这样就没有实现读读允许,意识到了后,加了个if判断解决了这一问题.在JA V A的线程的使用方法中,释放空间这个方法过去一直用的是notify(),但是由于一直是对单一的线程,这次实验中发现这个方法在这里不可行,所以即时查阅了资料用了notifyall()方法,总的来说,这次是操作系统的第一次实验,感觉最主要的是把脉络理清楚,写代码的工作要比理清脉络简单.。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验一实验报告学号:20092128 姓名:徐卓远实验序号:1实验名称:用信号量来实现读者-写者问题实验目的:理解进程同步与互斥的概念,掌握用信号量来实现进程的同步与互斥。

实验设计及实现:为了实现读者和写者的读写过程,将每个读者和每个写者作为了一个单独的线程,所以设置了两个类,一个是读者类Reader,一个是写者类Writer.以读者类为例:一个读者的动作过程为由睡眠->等待->开始读->结束读->睡眠的一个循环过程,而一个写者的动作过程也为此.读者调用方法napping()进行等待,调用startRead()方法开始读,最后在调用endReading()方法结束读入,释放运行空间.写者同读者.但是为了实现读者写者之间的写-写互斥,读-写互斥,读-读允许,需要另外一个类Database,类中分别用关于读者的方法和写者的方法来控制读写之间的这种关系.首先要实现睡眠的方法napping(),读者和写者在睡眠过程都应该是一样的,只是他们睡眠的时间不同,所以只需写出一个方法:public static void napping() {int sleepTime = (int) (NAP_TIME * Math.random()); try {Thread.sleep(sleepTime * 1000);} catch (Exception e) {e.printStackTrace();}}在方法中,控制线程休眠随机的时间,由于每个读者或写者都是一个线程,而每个读者或写者他们工作休眠的时间都不一定相同,他们请求工作的时间也不一定相同,所以取了随机时间其次设置了读者的两个方法,开始读和结束读,由于这只是个模拟读写问题,所以只需要知道结果就行,就不用显示出他是怎么读的.在开始读中,当有写者在写时,读者需要等待wait(),在没有人在工作时,如果有写者和读者同时请求,那么就让写者先进,这是写者优先.所以这就归纳于一种情况, 当读者布尔变量dbReading为FALSE时,如果有需要工作的写者,那么读者就等待.当读者请求读入后,计数有多少读者需要工作的变量readerCount +1,如果这是第一个进入工作的读者就需要将显示是否有读者在工作的读者布尔变量变为TRUE.public synchronized int startRead() {if (dbReading == false) {while (writerCount > 0) {try {System.out.println("reader is waiting");wait();} catch (Exception e) {System.out.println(e.toString());e.printStackTrace();}}}++readerCount;if (readerCount == 1) {dbReading = true;}return readerCount;}读结束时,计数需要读的读者数-1,然后释放出空间给需要工作的人.public synchronized int endReading() {--readerCount;if (readerCount == 0) {dbReading = false;}notifyAll();//释放出空间System.out.println("one reader is done, reading.Count=" + readerCount);return readerCount;}第三,编写关于写者的开始写和结束写方法,在开始写方法中,首先要将计数需要写的变量writerCount+1,写者如果有读者或者有写者正在工作,那么就等待,如果没有就直接进入写,然后表示是否有写者在写的布尔变量dbWriting变为TRUEpublic synchronized void startWriting() {//控制写者开始进入写++writerCount;while (dbReading == true || dbWriting == true) {try {System.out.println("Writer is waiting");wait();} catch (Exception e) {System.out.println(e.toString());}}dbWriting = true;}结束时只需将writerCount-1和dbWriting为FALSE,然后释放出空间.public synchronized void endWriting() {//控制写者结束写入--writerCount;dbWriting = false;System.out.println("one writer is done, writing.Count=" + writerCount);notifyAll();}源代码及程序流程图主类:package rw;/**** @author xzy*/public class Main {public static void main(String[] args) {Database db=new Database();//实例化类Database为dbReader r1=new Reader(1,db);//实例化类Reader为r1Reader r2=new Reader(2,db);Reader r3=new Reader(3,db);Reader r4=new Reader(4,db);Writer w1=new Writer(1,db);//实例化类Writer为w1Writer w2=new Writer(2,db);r1.start();//读者1调用start()方法开始进入读写这个模拟环境中r2.start();r3.start();w1.start();r4.start();w2.start();}}Database类:package rw;/**** @author xzy*/public class Database {private static final int NAP_TIME = 5;private int readerCount;//变量计数需要读的读者private int writerCount;//变量计数需要写的写者private boolean dbReading;//表示是否有读者在读private boolean dbWriting;//表示是否有写者在写public Database() {readerCount = 0;//变量计数需要读的读者为0writerCount = 0;//变量计数需要写的写者为0dbReading = false;//表示没有读者正在读入dbWriting = false;//表示没有写者正在写入}public static void napping() {//控制睡眠的时间int sleepTime = (int) (NAP_TIME * Math.random());//睡眠时间随机try {Thread.sleep(sleepTime * 1000);} catch (Exception e) {e.printStackTrace();}}public synchronized int startRead() {//控制读者开始读if (dbReading == false) {//当没有读者在读时while (writerCount > 0) {//当有写者想写时try {System.out.println("reader is waiting");wait();//等待} catch (Exception e) {System.out.println(e.toString());e.printStackTrace();}}}++readerCount;//请求读入的读者数加一if (readerCount == 1) {dbReading = true;//标明有读者正在读}return readerCount;}public synchronized int endReading() {//控制读者结束读入--readerCount;if (readerCount == 0) {dbReading = false;}notifyAll();//释放出空间给其他的线程System.out.println("one reader is done, reading. Count=" + readerCount);return readerCount;}public synchronized void startWriting() {//控制写者开始进入写++writerCount;//想写的写者数加一while (dbReading == true || dbWriting == true) {//当有读者在读或者有写者在写时都得等待try {System.out.println("Writer is waiting");wait();} catch (Exception e) {System.out.println(e.toString());}}dbWriting = true;}public synchronized void endWriting() {//控制写者结束写入--writerCount;dbWriting = false;System.out.println("one writer is done, writing. Count=" + writerCount);notifyAll();}}Reader类:package rw;/**** @author xzy*/public class Reader extends Thread {private Database server;//设置一个Database变量用来控制该读者private int readerNum;//设置该读者的标志public Reader(int r, Database db) {readerNum = r;server = db;}@Overridepublic void run() {int c;while (true) {System.out.println("reader " + readerNum + " is sleeping");Database.napping();//表明读者正在睡眠状态System.out.println("reader " + readerNum + " wants to read");c = server.startRead();//读者开始请求读入工作System.out.println("reader " + readerNum + " is reading. Count=" + c);Database.napping();//读者处于工作阶段c = server.endReading();//读者结束工作System.out.println("It is reader " + readerNum + " who has done reading according to count=" + c);}}}Writer类:package rw;/**** @author xzy*/public class Writer extends Thread {private Database server;//设置一个Database变量用来控制该写者private int writerNum;//设置该写者的标志public Writer(int w, Database db) {writerNum = w;server = db;@Overridepublic void run() {while (true) {System.out.println("Writer " + writerNum + " is sleeping");Database.napping();//表明写者正在睡眠状态System.out.println("Writer " + writerNum + " wants to write");server.startWriting();//写者开始请求读入工作System.out.println("Writer " + writerNum + " is writing");Database.napping();//写者处于工作阶段server.endWriting();//写者结束工作System.out.println("It is Writer " + writerNum + " who has done writing .");}}}写者:实验当堂所要完成的事情:解决编译和运行出现的问题.编译过程中出现的问题及其相应解决:1.一个读者或者写者工作完时无法释放出空间给其他人解决:用了notifyall()方法,最开始只知道notify()方法,要释放出空间给所有人平等使用权利那么就必须用notifyall()方法.运行过程中出现的问题及其相应解决:1.实现了写者优先但是没有实现读读允许解决:加了一个判断if,如果没有读者读才做出写者优先的判断.实验总结通过本次实验,我对读者-写者的过程有了清楚的认识,对互斥和同步有了更深一步的了解,在最开始的实验中,我没有正确理解好写者优先,当有写者等待时,读者就不能进入了,这样就没有实现读读允许,意识到了后,加了个if判断解决了这一问题.在JA V A的线程的使用方法中,释放空间这个方法过去一直用的是notify(),但是由于一直是对单一的线程,这次实验中发现这个方法在这里不可行,所以即时查阅了资料用了notifyall()方法,总的来说,这次是操作系统的第一次实验,感觉最主要的是把脉络理清楚,写代码的工作要比理清脉络简单.。

相关文档
最新文档