读者写者问题-操作系统实验报告

合集下载

读者写者实验报告

读者写者实验报告

读者写者实验报告
读者写者问题是指一个共享固定大小缓冲区的进程间通信问题,其中固定大小的缓冲区被多个读者进程和写者进程所共享。

读者进程从缓冲区中读取数据,而写者进程将数据写入缓冲区。

本实验目的是通过使用互斥锁、条件变量和信号量等同步机制,构建一个读者写者问题的解决方案。

实验环境:
- 操作系统:Linux
-编程语言:C语言
实验步骤:
1.创建共享内存缓冲区,用于读者和写者的数据传递。

2.创建互斥锁,用于保护共享内存缓冲区的访问。

3.创建条件变量,用于读者和写者之间的协调。

4.创建读者进程和写者进程,模拟读者写者的并发操作。

5.在读者进程中,通过互斥锁保护共享内存缓冲区,读取数据,并更新计数器。

6.在写者进程中,通过互斥锁保护共享内存缓冲区,写入数据,并更新计数器。

7.使用条件变量实现读者优先或写者优先的策略。

实验结果:
通过实验,我成功实现了读者写者问题的解决方案。

使用互斥锁可以保护共享资源的访问,防止读者和写者同时访问。

使用条件变量可以实现读者优先或写者优先的策略。

实验总结:
通过本次实验,我深入了解了读者写者问题,并且掌握了使用互斥锁、条件变量和信号量等同步机制来解决读者写者问题的方法。

在实现过程中,我遇到了一些困难,例如死锁和竞争条件等问题。


过调试和改进代码,我成功解决了这些问题,提高了程序的稳定性和性能。

在以后的工作中,我会更加注重并发编程的实践,提高自己解决问题
的能力。

2011211320周俊霞-读者写者问题实验报告(word文档良心出品)

2011211320周俊霞-读者写者问题实验报告(word文档良心出品)

操作系统试验--读者-写者问题周俊霞20112113202011211307班进程同步一.实习要求:本课程实验内容引自《Windows 内核实验教程》(陈向群、林斌等编著,机械工业出版社2002.9)。

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

用这n 个线程来表示n个读者或写者。

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

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

1.读者-写者问题的读写操作限制:1)写-写互斥;2)读-写互斥;3)读-读允许;2.读者优先的附加限制:如果一个读者申请进行读操作时已有另一读者正在进行读操作,则该读者可直接开始读操作。

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

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

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

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

第一字段为一个正整数,表示线程序号。

第一字段表示相应线程角色,R 表示读者是,W 表示写者。

第二字段为一个正数,表示读写操作的开始时间。

线程创建后,延时相应时间(单位为秒)后发出对共享资源的读写申请。

第三字段为一个正数,表示读写操作的持续时间。

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

下面是一个测试数据文件的例子:1 R 3 52 W 4 53 R 5 24 R 6 55 W 5.1 3三、与实验相关的API 介绍在本实验中可能涉及的API 有:线程控制:CreateThread 完成线程创建,在调用进程的地址空间上创建一个线程,以执行指定的函数;它的返回值为所创建线程的句柄。

操作系统实验报告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. 引言读者写者问题是操作系统中的经典同步问题,用于研究多线程环境下对共享资源的访问和保护。

在该问题中,有多个读者和写者同时对一个共享资源进行操作,需要保证并发访问时的正确性和效率。

通过本实验,我们将探讨读者写者问题的解决方案,并比较不同算法的性能差异。

2. 实验目标本实验的主要目标是通过实现和比较不同的读者写者问题算法,深入了解并发访问的挑战和解决方案。

具体而言,我们将研究以下几个方面:•设计并实现读者写者问题的解决方案•比较不同算法的性能差异•分析可能的优化策略3. 实验方法我们将使用Python编程语言来实现读者写者问题的解决方案。

在实验过程中,我们将尝试以下几种常见的算法:3.1. 读者优先算法在读者优先算法中,当有读者在访问共享资源时,其他读者可以同时访问,但写者需要等待。

只有当所有读者完成访问后,写者才能获得访问权限。

3.2. 写者优先算法在写者优先算法中,当有写者在访问共享资源时,其他读者和写者都需要等待。

只有当写者完成访问后,其他读者或写者才能获得访问权限。

3.3. 公平算法在公平算法中,读者和写者的访问权限是公平的,先到先得。

无论读者还是写者,都需要按照到达的顺序依次获取访问权限。

4. 实验步骤下面是我们实施实验的具体步骤:4.1. 实现基本的读者写者问题解决方案我们首先实现基本的读者写者问题解决方案,包括读者和写者的线程逻辑和共享资源的访问控制。

我们将使用互斥锁和条件变量来保证并发访问的正确性。

4.2. 实现读者优先算法在已有的基本解决方案的基础上,我们实现读者优先算法。

我们将通过优化访问控制的逻辑来实现读者优先的特性。

4.3. 实现写者优先算法类似地,我们在基本解决方案的基础上实现写者优先算法。

我们将调整访问控制的逻辑,使得写者优先于其他读者和写者。

4.4. 实现公平算法最后,我们实现公平算法。

我们将结合队列和条件变量等技术来确保读者和写者的访问顺序是公平的。

操作系统实验报告_读者写者问题

操作系统实验报告_读者写者问题
}
void WP_WriterThread(void * p) //---------------------------写者优先--写者线程
{
HANDLE h_Mutex1;//互斥变量
h_Mutex1 = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutexl");
HANDLE h_Mutex2;
h_Mutex2 = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex2");
DWORD wait_for_mutex1; //等待互斥变量所有权
};
void RP_ReaderThread(void * p) //---------------------------读者优先--读者线程
{
HANDLE h_Mutex;//互斥变量
//OpenMutex函数功能:为现有的一个已命名互斥体对象创建一个新句柄
h_Mutex = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_readcount");
(附注释)
#include "stdafx.h"
#include"windows.h"
#include<conio.h>
#include<stdlib.h>
#include<fstream.h>
#include<io.h>
#include<string.h>
#include<stdio.h>
#define READER 'R' //读者

操作系统读者写者问题报告

操作系统读者写者问题报告

操作系统读者写者问题报告
读者写者问题是一种典型的操作系统同步问题,其描述如下:有多个读者和写者同时访问共享资源,读者可以同时访问共享资源,但写者必须独占式的访问共享资源,即任何时刻只能有一个写者访问共享资源,且在写者访问共享资源的期间,任何读者都不得访问共享资源。

此外,读者在访问共享资源时不会修改共享资源,而写者则会对共享资源进行修改。

如何实现读者写者问题呢?简单来说,可以使用信号量机制来解决这个问题。

具体来说,可以使用两个信号量RdMutex和WrMutex,RdMutex用于锁定读者,在读者访问共享资源时,需要申请RdMutex信号量,如果有写者在访问共享资源,则RdMutex会阻止读者访问共享资源;而当最后一个读者结束访问共享资源时,需要释放RdMutex信号量,以便让其他等待的读者访问共享资源。

类似地,WrMutex用于锁定写者,在写者访问共享资源时,需要申请WrMutex信号量,如果有其他读者或者写者在访问共享资源,则WrMutex会阻止写者访问共享
资源;而当写者访问共享资源结束时,需要释放WrMutex信号量,以便让其他等待的写者访问共享资源。

除了信号量机制之外,还可以使用其他同步机制来解决读者写者问题,比如互斥量、条件变量等。

同时,操作系统还可以采用优化策略,比如写优先、读写优先等,来提高读写效率。

总之,读者写者问题是操作系统同步问题中的一个经典问题,其实现方式需要考虑多方面的因素,包括并发访问、同步机制、优化策略等,需要经过深入思考和有效实践才能得到较好的解决方案。

读者写者问题实验报告

读者写者问题实验报告引言读者写者问题是计算机科学中经典的同步问题之一,它涉及多线程编程中的资源竞争与同步机制。

通过对读者写者问题的研究,我们可以深入理解线程同步的重要性,并掌握解决并发编程中可能出现的竞争条件和死锁等问题的方法。

在本实验中,我们将设计并实现一个简单的读者写者问题的解决方案,并通过模拟多个读者和写者的并发访问来验证方案的正确性和效果。

问题描述读者写者问题可描述为:有一共享资源(如文件、数据库等),读者可同时访问共享资源进行读取操作,但写者在进行写入操作时,不可同时被其他任何读者或写者访问。

读者和写者的并发访问需要由线程同步机制来保证共享资源的一致性和完整性。

实验设计与实现为了解决读者写者问题,我们需要考虑以下几个关键点:1. 共享资源的访问控制我们可以使用互斥量(Mutex)来实现对共享资源的访问控制。

当一个线程访问共享资源时,它需要先获得互斥量的锁,如果锁已被其他线程占用,则线程进入等待状态,直到锁可用。

一旦线程完成对共享资源的访问,它将释放锁,以便其他线程继续访问。

2. 读者与写者的优先级在读者写者问题中,我们往往需要设定某个优先级规则,以确定读者和写者之间的调度顺序。

一种常见的策略是给予写者优先级,即当一个写者在等待访问共享资源时,其他读者都必须等待。

这样做是为了避免写者长时间等待,以免造成饥饿问题。

3. 记录读者和写者的数量为了控制读者和写者的并发访问,我们需要记录当前同时访问共享资源的读者和写者的数量。

我们可以使用整数变量来记录读者和写者的数量,并通过信号量来保证对这些计数变量的互斥访问。

4. 同步机制的设计在实现读者写者问题的解决方案时,我们需要考虑如何合理地使用互斥量和信号量,并结合优先级规则来实现读者和写者的同步。

这需要通过仔细的设计和调试来确保解决方案的正确性。

实验结果与分析我们基于上述设计实现了一个读者写者问题的解决方案,并进行了多次仿真实验。

实验环境•操作系统:Windows 10•编程语言:C++•编译器:GCC实验步骤1.编写读者和写者线程的代码,其中涉及到对共享资源的读取和写入操作,以及对计数变量和互斥量的访问操作。

操作系统读者写者实验报告


g_hReadSemaphore = CreateSemaphore(NULL,1,100,NULL); //创建信号 灯,当前可用的资源数为1,最大为100 g_hWriteSemaphore = CreateSemaphore(NULL,1,100,NULL); //创建信号 灯,当前可用的资源数为1,最大为100 CreatePersonList(g_PersonLists); // Create All the reader and writers printf("Created all the reader and writer\n...\n"); g_CurrentTime = 0; while(true) { g_CurrentTime++; Sleep(300); // 300 ms printf("CurrentTime = %d\n",g_CurrentTime); if(finished) return 0; } // return 0; } void CreatePersonList(int *pPersonLists) { int i=0; int *pList = pPersonLists; bool Ret; while(pList[0] != END) { switch(pList[1]) { case R: Ret = CreateReader(pList[2],pList[3],pList[0]);//351,w452,523,654 break; case W: Ret = CreateWriter(pList[2],pList[3],pList[0]);
. Perform reader operation; Ssignal(L,1); Until false; End Writer :begin Repeat Swait(mx ,1,1,l,RN,0); Perform writer operation; Ssignal(mx,1); Until false; End Parend End 其中,Swait(mx,1,0)语句起着关作用,只要无Writer进程进入 些,mx=1,reader进程就都可以进入读。但是要一旦有Writer进程进入 写时,其MX=0,则任何reader进程就都无法进入读。Swait(mx ,1,1,l,RN,0)语句表示仅当既无Write进程在写(mx=1),又无reader进程 在读(L=RN)时,writer进程才能进入临界区写。 本设计方案就是通过利用记录型信号量对读者写者问题的解决过程 进行模拟演示,形象地阐述记录型信号量机制的工作原理。

读者写者实验报告

操作系统原理实验报告实验名称:操作系统姓名: XXX学号: xxxxxxxxxx班级: xxx指导老师: xxx一、实验内容在Windows2000环境下,创建一个控制台进程,此进程包含n个线程。

用这n个线程来表示n个读者或写者。

每个线程按相应测试数据文件(后面有介绍)的要求进行读写操作。

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

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

2)读-写互斥,即不能同时有一个线程在读,而另一个线程在写。

,3)读-读允许,即可以有一个或多个读者在读。

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

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

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

二、实验目的在Windows2000环境下,创建一个控制台进程,此进程包含n个线程。

用这n 个线程来表示n个读者或写者。

每个线程按相应测试数据文件(后面有介绍)的要求进行读写操作。

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

三、实验原理1).读者优先读者优先指的是除非有写者在写文件,否则读者不需要等待。

所以可以用一个整型变量read_count记录当前的读者数目,用于确定是否需要释放正在等待的写者线程(当read_count=O时,表明所有的读者读完,需要释放写者等待队列中的一个写者)。

每一个读者开始读文件时,必须修改read_count变量。

因此需要一个互斥对象mutex来实现对全局变量read_count修改时的互斥。

另外,为了实现写-写互斥,需要增加一个临界区对象write。

操作系统读者写者实验报告

操作系统读者写者实验报告一、实验目的通过实验理解读者写者问题的实现原理,掌握相关的同步机制,实现读者写者问题的经典解法,并对比不同解法的优缺点。

二、实验原理1.读者写者问题读者写者问题是指在多个线程同时读写一个共享数据的情况下可能出现的问题。

其问题的核心在于多个读线程可以同时读,但只能有一个写线程能够写,并且在写操作过程中不能有任何的读操作。

2.互斥与同步为了解决读者写者问题,在多线程并发读写共享数据时,需要使用互斥与同步机制来保证数据的完整性和一致性。

-互斥:通过锁机制来保证只允许一个线程进入临界区,其他线程需要等待锁的释放。

-同步:通过信号量等机制来保证线程按照一定顺序执行。

三、实验步骤本次实验中将实现两个版本的读者写者问题解决方案:一是使用互斥锁和条件变量,二是使用信号量。

1.使用互斥锁和条件变量(1)定义全局变量和互斥锁:共享数据、读者数目、互斥锁、写者条件变量、读者条件变量。

(2)初始化互斥锁和条件变量。

(3)写者线程的实现:获取互斥锁,判断当前是否有读者或写者,如果有则等待条件变量,然后进行写操作,释放互斥锁。

(4)读者线程的实现:获取互斥锁,判断是否有写者,如果有则等待条件变量,否则增加读者数目并释放互斥锁,进行读操作。

(5)测试程序的运行并输出结果。

2.使用信号量(1)定义全局变量和信号量:共享数据、读者信号量、写者信号量、用于保护读者数目和写者数目的互斥信号量。

(2)初始化信号量和互斥信号量。

(3)写者线程的实现:首先获取写者互斥信号量,然后获取写者信号量,进行写操作,释放写者信号量和写者互斥信号量。

(4)读者线程的实现:首先获取读者互斥信号量,然后增加读者数目,如果是第一个读者则获取写者信号量,然后进行读操作,释放读者信号量和读者互斥信号量,如果是最后一个读者则释放写者信号量。

(5)测试程序的运行并输出结果。

四、实验结果与分析通过对比两种解决方案,可以得出以下结论:1.使用互斥锁和条件变量的解决方案相对较为简单,但可能存在饥饿问题,即可能会导致一些线程一直无法访问共享资源。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
wq.writers[wq.index++]=write_id;//将写者进程加入等待队列
wcount++;
return;
}
}
if(w == 1){
w--;
printf("写者%d正在写\n请输入要写的内容",write_id);
scanf("%s",temp);
//while
}//if
}
//************************读者优先时唤醒进程
printf("!有读者在读不能写!\n");
wq.writers[wq.index++]=write_id;//将写者进程加入等待队列
wcount++;
return;
}
if(rcount == 0 ){//rcount == 0则当前无读者,但w = 0,所以有写者在写
printf("!有写者在写不能写!\n");
sign = 1;//temp中已经有内容要置1
for(i=0;i<=m;i++){//index为当前读者队列中的等待进程数
void RFwakeup(){
int i = 0;
int j = 0;
int m,n;
m = rq.index;
//n = wq.index;
if(rcount == 0){//当前无读进程,是写者在写--》停止运行写进程
bool reader_wait=false;
w=1;
printf("写者已经写完\n");
2.根据实验要求完善功能:由用户决定写者向缓冲区中写入的内容,读者能够读出并显示出来;当缓冲区中没有数据时,读者要等待,直到缓冲区中有数据才能读
3.根据“读者优先”加以改变,增加一个“写者优先”模式,并且由用户来选择模式
源代码:
#include<stdio.h>
#include<stdlib.h>
int rcount=0;//正在读的读者数量
int wcount=0;//写者队列中等待写操作的写者数量
int read_id=0;//读进程号
int write_id=0;//写进程号
int w=1;//读写互斥信号量
char temp[300] = {'\0'};
int choice; //用户选择读者优先OR写者优先
int sign; //标识temp空的信号量0表示temp空
if(temp[i] == '\0'){
printf("\n");
return;
}
printf("%c",temp[i]);
}//for
}//else
}
//***************************写进程写操作
void write(){
write_id++;
if(w == 0){
if(rcount != 0 ){//有读者进程在执行
void WFwakeup();
void RFwakeup();
struct rqueue{//读者等待队列
int readers[200];
int index;
}rq;
struct wqueue{//写者等待队列
int writers[200];
int index;
}wq;
/*void first(){ //初始化
实验内容
1、定义一个数据缓存buffer及用于实现同步互斥的信号量。
2、定义一个读者函数:
当有写者在占用buffer时,读者应该等待,直到写者不再使用该buffer。
当有其他读者在占用buffer时,读者可对buffer进行读取操作。
当buffer中有数据时,则从其中读取一个数据,并显示然后退出。
当buffer中没有数据时,应等待,直到buffer中有数据可读。
int i = 0;
read_id++;
if(rcount == 0){//当前没有读进程在读可能有写进程在写可能CPU空闲
if(w==1) {//如果CPU空闲,读者拿到CPU
w--;//相当于一个P操作
rcount++;
if(temp[0] == '\0'){
sign = 0;
if(choice == 1){
int i;
rq.index = 0;
wq.index = 0;
for(i = 0;i<20;i++){
rq.readers[i] = 0;
wq.writers[i] = 0;
}
}*/
//*******************************************读进程读操作
void read(){
for(i = 0;i < 300;i++){//读取temp内容即写者写的内容
if(temp[i] == '\0'){
printf("\n");
return;
}//if
printf("%c",temp[i]);
}//for
}//if
else{//写者线程正在执行
printf("!有写者在写不能读!\n");
rq.readers[rq.index++]=read_id;//将读者进程加入等待队列
}//else
}//if
else{//rcount !=1则知道当前已经有读者在读,读读不互斥,则这个读者可以直接进来了读
printf("读者%d正在读\n",read_id);
for(i = 0;i < 300;i++){
4、定义主函数,在其中可以任意创建读者与写者。
可根据用户输入创建读者或写者进程(线程)。
5、用户界面
实验当堂所要完成事情列表:
1.调试程序使其在读者优先模式下可以运行并且能实现基本的功能得出正确的结果:能够实现读写互斥,写写互斥,读读不互斥,一个进程结束能够唤醒等待队列中的进程(先读者队列后写,写者应该等待,直到所有的读者都退出为止。
当有其他写者占用buffer时,该写者应该等待,直到占用buffer的写者退出为止。
当buffer有空闲时,写者应该在buffer中写入一个数据并退出。
当buffer满时,写者应该等待,直到buffer有空闲为止。
rq.readers[rq.index++]=read_id;//将读者进程加入等待队列
RFwakeup();
return;
}
else{
rq.readers[rq.index++]=read_id;//将读者进程加入等待队列
WFwakeup();
return;
}
}//if
printf("读者%d正在读\n",read_id);
相关文档
最新文档