操作系统读者写者实验报告
操作系统实验报告(读者写着问题,时间片轮转算法,内存的分配,进程的调度)

电子科技大学计算机学院实验中心小心计算机专业类课程实验报告课程名称:操作系统学 院:软件学院专 业:软件工程学生姓名:李 希学 号:2010231020018指导教师:丁老师日 期: 2012年5月5日电子科技大学实验报告实验一一、实验名称:进程管理二、实验学时:4三、实验内容和目的:实验内容:(1)进程的创建写一段源程序,创建两个进程,当此程序运行时,在系统中有一个父进程和两个子进程活动。
让每一个进程在屏幕上显示字符。
观察纪录屏幕上的显示结果,然后分析原因。
(2)进程的控制修改编写的程序,将每个进程输出一个字符改为每个进程输出一句话,在观察程序执行时屏幕出现的现象,并分析原因。
实验目的:(1)加深对进程概念的理解,明确进程和程序的区别。
(2)进一步认识并发执行的实质。
(3)分析进程竞争资源现象,学习解决进程互斥的方法。
四、实验原理:利用fork函数来创建子进程,并返回子进程的ID号。
利用lockf函数来实现信号量对进程的资源竞争的调度,和互斥的方法。
五、实验器材(设备、元器件):一台装有VS2010的电脑,操作系统为WIN7.六、实验步骤:(1)先写好2个子进程程序,并且让2个子程序在屏幕上分别打印出A,B(2)父进程创建2个子进程,并在屏幕上打印出C。
(3)观察进程竞争资源的现象。
七、实验数据及结果分析:电子科技大学计算机学院实验中心子进程A的代码:#include<iostream>#include<windows.h>using namespace std;int main(){cout<<"I'm Process A/n"<<endl;return 0;}子进程B的代码:#include<iostream>using namespace std;int main(){cout<<"I'm Process B"<<endl;;return 0;}父进程C的代码://#include "stdafx.h"#include<windows.h>#include<iostream>using namespace std;void print_error(){DWORD nErrorNo = GetLastError ( );LPSTR lpBuffer;FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS |FORMAT_MESSAGE_FROM_SYSTEM,NULL,nErrorNo,LANG_NEUTRAL,(LPTSTR) & lpBuffer,0 ,NULL );if (lpBuffer == NULL){lpBuffer = "Sorry, cannot find this error info. ";}printf("%s (%d).\n", lpBuffer, nErrorNo);}int fork(const char* pszApplication,HANDLE& hProcess){STARTUPINFO si={sizeof(si)};PROCESS_INFORMATION pi;if(!CreateProcess(pszApplication,NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) return -1;else{hProcess=pi.hProcess;return pi.dwProcessId;}}void lockf(HANDLE hObj){DWORD state = WaitForSingleObject(hObj,INFINITE);switch (state){case WAIT_OBJECT_0:printf("\nProcess exit.\n");break;case WAIT_TIMEOUT:printf("\nTime out.\n");break;case WAIT_FAILED:printf("\nWait Failed.\n");print_error();break;}}int main(int argc, char* argv[]){HANDLE hProcess1,hProcess2;int child1=fork("C:\\操¨´作Á¡Â系¦Ì统ª3实º¦Ì验¨¦\\ProcessA\\Debug\\ProcessA.exe",hProcess1);if(-1==child1){cout << "fork error!\n";return -1;}lockf(hProcess1);电子科技大学计算机学院实验中心int child2=fork("C:\\操¨´作Á¡Â系¦Ì统ª3实º¦Ì验¨¦\\ProcessB\\Debug\\ProcessB.exe",hProcess2);if(-1==child2){cout << "fork error!\n";return -1;}cout<<"This is Process C\n";lockf(hProcess2);return 0;}程序运行的结果:八、实验结论、心得体会和改进建议:实验结论:成功的通过了父进程C来创建了2个子进程A,B,并成功的对子进程进行了调度与管理。
读者写者实验报告

读者写者实验报告
读者写者问题是指一个共享固定大小缓冲区的进程间通信问题,其中固定大小的缓冲区被多个读者进程和写者进程所共享。
读者进程从缓冲区中读取数据,而写者进程将数据写入缓冲区。
本实验目的是通过使用互斥锁、条件变量和信号量等同步机制,构建一个读者写者问题的解决方案。
实验环境:
- 操作系统:Linux
-编程语言:C语言
实验步骤:
1.创建共享内存缓冲区,用于读者和写者的数据传递。
2.创建互斥锁,用于保护共享内存缓冲区的访问。
3.创建条件变量,用于读者和写者之间的协调。
4.创建读者进程和写者进程,模拟读者写者的并发操作。
5.在读者进程中,通过互斥锁保护共享内存缓冲区,读取数据,并更新计数器。
6.在写者进程中,通过互斥锁保护共享内存缓冲区,写入数据,并更新计数器。
7.使用条件变量实现读者优先或写者优先的策略。
实验结果:
通过实验,我成功实现了读者写者问题的解决方案。
使用互斥锁可以保护共享资源的访问,防止读者和写者同时访问。
使用条件变量可以实现读者优先或写者优先的策略。
实验总结:
通过本次实验,我深入了解了读者写者问题,并且掌握了使用互斥锁、条件变量和信号量等同步机制来解决读者写者问题的方法。
在实现过程中,我遇到了一些困难,例如死锁和竞争条件等问题。
通
过调试和改进代码,我成功解决了这些问题,提高了程序的稳定性和性能。
在以后的工作中,我会更加注重并发编程的实践,提高自己解决问题
的能力。
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

操作系统实验报告实验题目: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());}}}}四.实验结果:运行如下:。
读者-写者 操作系统实验报告 计算机操作系统

4.1实验二:读者写者问题4.1.1实验要求在Windows 环境下,创建一个控制台进程,此进程包含n个线程。
用这n个线程来表示n个读者或写者。
每个线程按相应测试数据文件(后面有介绍)的要求进行读写操作。
用信号量机制分别实现读者优先和写者优先的读者-写者问题。
读者-写者问题的读写操作限制(包括读者优先和写者优先):1)写-写互斥,即不能有两个写者同时进行写操作。
2)读-写互斥,即不能同时有一个线程在读,而另一个线程在写。
3)读-读允许,即可以有一个或多个读者在读。
读者优先的附加限制:如果一个读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。
写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态才能开始读操作。
运行结果显示要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结果读写操作时分别显示一行提示信息,以确定所有处理都遵守相应的读写操作限制。
4.1.2测试数据文件格式测试数据文件包括n行测试数据,分别描述创建的n个线程是读者还是写者,以及读写操作的开始时间和持续时间。
每行测试数据包括四个字段,各个字段间用空格分隔。
第一字段为一个正整数,表示线程序号。
第二字段表示相应线程角色,R表示读者,W表示写者。
第三字段为一个正数,表示读写操作的开始时间:线程创建后,延迟相应时间(单位为秒)后发出对共享资源的读写申请。
第四字段为一个正数,表示读写操作的持续时间。
当线程读写申请成功后,开始对共享资源的读写操作,该操作持续相应时间后结束,并释放共享资源。
下面是一个测试数据文件的例子:1 R 3 52 W 4 53 R 5 24 R 6 55 W 5.1 3注意:在创建数据文件时,由于涉及到文件格式问题,最好在记事本中手工逐个键入数据,而不要拷贝粘贴数据,否则,本示例程序运行时可能会出现不可预知的错误。
4.1.3实习分析可以将所有读者和所有写者分别存于一个读者等待队列和一个写者等待队列中,每当读允许时,就从读者队列中释放一个或多个读者线程进行读操作;每当写允许时,就从写者队列中释放一个写者进行写操作。
读者写者问题实验报告

读者写者问题实验报告1. 引言读者写者问题是操作系统中的经典同步问题,用于研究多线程环境下对共享资源的访问和保护。
在该问题中,有多个读者和写者同时对一个共享资源进行操作,需要保证并发访问时的正确性和效率。
通过本实验,我们将探讨读者写者问题的解决方案,并比较不同算法的性能差异。
2. 实验目标本实验的主要目标是通过实现和比较不同的读者写者问题算法,深入了解并发访问的挑战和解决方案。
具体而言,我们将研究以下几个方面:•设计并实现读者写者问题的解决方案•比较不同算法的性能差异•分析可能的优化策略3. 实验方法我们将使用Python编程语言来实现读者写者问题的解决方案。
在实验过程中,我们将尝试以下几种常见的算法:3.1. 读者优先算法在读者优先算法中,当有读者在访问共享资源时,其他读者可以同时访问,但写者需要等待。
只有当所有读者完成访问后,写者才能获得访问权限。
3.2. 写者优先算法在写者优先算法中,当有写者在访问共享资源时,其他读者和写者都需要等待。
只有当写者完成访问后,其他读者或写者才能获得访问权限。
3.3. 公平算法在公平算法中,读者和写者的访问权限是公平的,先到先得。
无论读者还是写者,都需要按照到达的顺序依次获取访问权限。
4. 实验步骤下面是我们实施实验的具体步骤:4.1. 实现基本的读者写者问题解决方案我们首先实现基本的读者写者问题解决方案,包括读者和写者的线程逻辑和共享资源的访问控制。
我们将使用互斥锁和条件变量来保证并发访问的正确性。
4.2. 实现读者优先算法在已有的基本解决方案的基础上,我们实现读者优先算法。
我们将通过优化访问控制的逻辑来实现读者优先的特性。
4.3. 实现写者优先算法类似地,我们在基本解决方案的基础上实现写者优先算法。
我们将调整访问控制的逻辑,使得写者优先于其他读者和写者。
4.4. 实现公平算法最后,我们实现公平算法。
我们将结合队列和条件变量等技术来确保读者和写者的访问顺序是公平的。
读者-写者问题解答计算机操作系统实验报告指导资料

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

北京电子科技学院(BESTI)实验报告课程:操作系统班级:0921 姓名:学号:成绩:指导教师:徐小青实验日期:2011.11.22 实验密级:/ 预习程度:代码实验时间:12:50-15:20 仪器组次:A04 必修/选修:必修实验序号:(一)实验名称:用信号量来实现读者-写者问题实验目的与要求:理解进程(或线程)及信号量的概念实验仪器:一、实验目的:理解进程(或线程)及信号量的概念二、实验内容:1、定义一个数据缓存buffer及用于实现同步互斥的信号量。
2、定义一个读者函数:●当有写者在占用buffer时,读者应该等待,直到写者不再使用该buffer。
●当有其他读者在占用buffer时,读者可对buffer进行读取操作。
●当buffer中有数据时,则从其中读取一个数据,并显示然后退出。
●当buffer中没有数据时,应等待,直到buffer中有数据可读。
3、定义一个写者函数●当有读者在占用buffer时,写者应该等待,直到所有的读者都退出为止。
●当有其他写者占用buffer时,该写者应该等待,直到占用buffer的写者退出为止。
●当buffer有空闲时,写者应该在buffer中写入一个数据并退出。
●当buffer满时,写者应该等待,直到buffer有空闲为止。
4、定义主函数,在其中可以任意创建读者与写者。
可根据用户输入创建读者或写者进程(线程)。
三、实验当堂完成内容:1,将设计好的思路以代码形式呈现,并调通。
2,将数据改变,看结果是否符合预期设想3,与同学交流,将代码完善。
四、设计思想:读进程:read(){P(Sr); 申请区域P(Scot); 锁定读者计数器first = first+1;if(first ==1)P(Sdoc);V(Scnt); 解锁读者计数器开始读;P(Scnt); 锁定读者计数器V(Sdoc);V(Scnt);V(Sr);}写进程:write(){P(sdoc);开始写;V(sdoc);}主函数设计思想:五、代码及具体解释:#include <stdlib.h>#include <windows.h>#include <stdio.h>#define P(S) WaitForSingleObject(S, INFINITE)// 这是Windows 下多线程工作的P 操作#define V(S) ReleaseSemaphore(S, 1, NULL)// 这是Windows 下多线程工作的V 操作const int RN = 5 ; // 所有读者总数(可以改变)const int WN = 3; // 所有写者总数(可以改变)HANDLE Sdoc; // 文档信号量——互斥量(临界区的信号量题目要求是1)HANDLE Sr; // 读者信号量——广义信号量(一次最多有多少个读者在读)HANDLE Scnt; // 保护g_cntReader 的互斥量(目前有多少读者正在读)int g_cntReader = 0; // 读者个数计数器// funcname : JustWait ( )// note: 显示一些信息,让后等待// ret val : void//// + Parameter :// [ int ] - nReader 读者(写者)编号,读者>0,写者<0// [ int ] - min 操作等待的最短时间// [ int ] - max 操作等待得最长时间,实际等待的时间介于两者之间// [ LPCSTR ] - info 要显示的信息void JustWait(int nReader, int min, int max, LPCSTR info);DWORD WINAPI Reader(LPVOID lpPara);DWORD WINAPI Writer(LPVOID lpPara);// 这是主函数void main(){Sdoc = CreateSemaphore(NULL, 1, 1, "Document");// 创建信号量初值,最大信号量值Sr = CreateSemaphore(NULL, 3, 3, "ReaderNumber"); // 一次最多允许3 个Scnt = CreateSemaphore(NULL, 1, 1, "ReaderCounterProtect");// 他也是一个互斥信号量,初值为 1HANDLE threads[RN+WN];for (int i=0; i<RN; i++) //不断创建读者线程threads[i] = CreateThread(0, 0, Reader, 0, 0, 0);for (int j=0; j<WN; j++)threads[j+RN] = CreateThread(0, 0, Writer, 0, 0, 0);WaitForMultipleObjects(RN+WN, threads, TRUE, INFINITE);}// 读者线程DWORD WINAPI Reader(LPVOID lpPara){// 注意是静态变量,可以使每来一个读者增加一static int reader_num = 1;int i = reader_num ++;int x=0;while (x<=5){JustWait(i, 1, 2, "我想读"); //1s的时候来,给2s的时间去读P(Sr); // 读者未满P(Scnt); // 锁定读者计数器printf("还有%d 个读者在读, 读者%d进入\n", g_cntReader, i);g_cntReader ++;if (g_cntReader == 1) // 如果是第一个读者{JustWait(i, 1, 2, "我是第一个!");P(Sdoc); // 锁定文档printf("读者%d说:有人在读,不可写文件\n", i);JustWait(i, 1, 2, "我可以读文件了!");V(Scnt); // 解锁读者计数器释放JustWait(i, 2, 5, "我在读");// 读ing…………JustWait(i, 1, 2, "我将要离开!");P(Scnt); // 锁定读者计数器g_cntReader --;if (g_cntReader == 0) // 如果是最后一个{JustWait(i, 1, 2, "我是最后一个!");printf("读者%d说:可以对文件操作了!~~~\n", i);V(Sdoc);// 解锁文档}printf("还有%d个读者在, 读者%d离开\n", g_cntReader, i);V(Scnt);// 解锁读者计数器V(Sr); // 离开JustWait(i, 5, 3, "结束");x++;printf("%d\n",x);}return 0;}DWORD WINAPI Writer(LPVOID lpPara){// 注意是静态变量,可以使每来一个写者减去一,注意初值是负值static int g_cnt = -1;int j = g_cnt --;while (1){JustWait(j, 2, 4, "我想写");// 锁定文档P(Sdoc);printf("\t写者%d说:文件正在修改不可操作\n", -j);JustWait(j, 4, 3, "写···"); // 写ing……JustWait(j, 1, 2, "写完了,离开");printf("写者%d说:可以对文件操作了\n", -j);V(Sdoc);// 解锁文档JustWait(j, 8, 4, "休息了");}return 0;}void JustWait(int nReader, int min, int max, LPCSTR info)//min为读者到来时间,max为读者离开时间{const int BASETIME = 1000;// 等待时间的基本量,以毫秒表示int wait_time = 0;// 实际等待得时间if (max==min) // 判断是为了避免%0错误,注意取随机值wait_time = min*BASETIME;//处理时间为0;elsechar s_out[128];// 最终显示的信息缓冲if (nReader > 0)// 读者大于0,写者小于0sprintf(s_out, "读者%d说: %s\n", nReader, info);elsesprintf(s_out, "\t写者%d说: %s\n", -nReader, info);printf(s_out);// 打印Sleep(wait_time);// 然后等待}//其设计思想是:读者在读,来了写着,创建写着线程,利用时间片区分他们。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《操作系统》上机实验报告实验项目读者写者学院(部)信息学院专业计算机科学与技术班级学生姓名学号读者写者问题一.实验目的:1.熟悉读者优先和写者优先的过程。
2.更好地理解进程同步的概念及其实现方法。
二.实验要求:分别实现读者优先和写者优先。
“读-写”互斥,即不能同时有一个读者在读,同时去有一个写者在写;“写-写”互斥,即不能有两个写者同时进行写操作;“读-读”允许,即可以有两个以上的读者同时进行读操作。
三.实验内容:读者优先:如果没有写者正在操作,则读者不需要等待,用一个整型变量readcount 记录当前的读者数目,用于确定是否释放写者线程,(当readcout=0 时,说明所有的读者都已经读完,释放一个写者线程),每个读者开始读之前都要修改readcount,为了互斥的实现对readcount 的修改,需要一个互斥对象Mutex来实现互斥。
另外,为了实现写-写互斥,需要一个临界区对象write,当写者发出写的请求时,必须先得到临界区对象的所有权。
通过这种方法,可以实现读写互斥,当readcount=1 时,(即第一个读者的到来时,),读者线程也必须申请临界区对象的所有权.当读者拥有临界区的所有权,写者都阻塞在临界区对象write上。
当写者拥有临界区对象所有权时,第一个判断完readcount==1 后,其余的读者由于等待对readcount的判断,阻塞在Mutex上!写者优先:写者优先和读者优先有相同之处,不同的地方在:一旦有一个写者到来时,应该尽快让写者进行写,如果有一个写者在等待,则新到的读者操作不能读操作,为此添加一个整型变量writecount,记录写者的数目,当writecount=0时才可以释放读者进行读操作!为了实现对全局变量writecount的互斥访问,设置了一个互斥对象Mutex3。
为了实现写者优先,设置一个临界区对象read,当有写者在写或等待时,读者必须阻塞在临界区对象read上。
读者除了要一个全局变量readcount实现操作上的互斥外,还需要一个互斥对象对阻塞在read这一个过程实现互斥,这两个互斥对象分别为mutex1和mutex2。
四.实验结果1.实验数据:读者优先:r w r w r 写者优先:r w r w r结果展示:五.实验总结这次实验分读者优先和写者优先来处理,不仅掌握了读者写者的过程和原理,而且还了解到了读者优先和写者优先之间的联系,共同点和不同点。
写代码的过程中出现了许多的问题,最先开始没有用进程来实现,发现比较困难,而且模拟的不真实,后来有从网上面学习了一些进程的东西,借鉴了他人的一些经验完成了这次的报告。
六.实验代码#include <windows.h>#include <conio.h>#include "fstream.h"int readcount=0; //读者数目int writecount=0; //写者数目CRITICAL_SECTION RP_Write; //临界区CRITICAL_SECTION cs_Write;CRITICAL_SECTION cs_Read;struct ThreadInfo //线程信息{ int Threadhao; //线程序号char ThreadClass; //线程类别double ThreadStartTime; //线程开始时间double ThreadRunTime; //线程读写持续时间};void ReaderFun(char* file);//读者优先函数void R_ReaderThread(void *p);//处理读者优先读者线程void R_WriterThread(void *p);//处理读者优先写者线程void WriterFun(char* file);void W_ReaderThread(void *p);void W_WriterThread(void *p);int main()//主函数{char select;while (true){cout<<"1:读者优先"<<endl;cout<<"2:写者优先"<<endl;cout<<"3:退出"<<endl;cout<<" "<<endl;cout<<"请选择要进行的操作:"<<endl;do{cin>>select;if(select!='1' && select!='2' && select!='3')cout<<"你操作有误,请重试!"<<endl;}while (select!='1' && select!='2' && select!='3');system("cls");if (select=='3')return 0;//退出else if (select=='1')//调用读者优先ReaderFun("110.txt");else if(select=='2')//调用写者优先WriterFun("110.txt");cout<<"\n是否还有继续? 1. 继续 2.退出"<<endl;;do{cin>>select;if(select!='1' && select!='2' )cout<<"你操作有误,请重试!"<<endl;}while (select!='1' && select!='2');if(select=='2')return 0;// 退出system("cls");}return 0;}//读者优先函数void ReaderFun(char* file){DWORD n_thread=0; //线程数初值为0DWORD thread_ID; //线程IDDWORD wait_for_all; //等待所有线程结束//临界资源HANDLE h_Mutex;//互斥对象(h_Mutex)确保线程拥有对单个资源的互斥访问权h_Mutex=CreateMutex(NULL,FALSE,"mutex_for_readcount");HANDLE h_Thread[64]; //线程对象数组,最大64ThreadInfo thread_info[64];readcount=0;InitializeCriticalSection(&RP_Write); //初始化临界区ifstream inFile;inFile.open(file);cout<<"读者优先:\n"<<endl;while (inFile){//读入每一个读者、写者的信息inFile>>thread_info[n_thread].Threadhao>>thread_info[n_thread].ThreadClass>>thread_info[n_thread].ThreadStartTime>>thread_info[n_thread].ThreadRunTime;if (-1 == inFile.get())break;n_thread++;//线程数加一}for (int i=0;i<(int)(n_thread);i++){if (thread_info[i].ThreadClass=='r')//创建读者线程h_Thread[i]=CreateThread(NULL,0,\(LPTHREAD_START_ROUTINE)(R_ReaderThread),\&thread_info[i],0,&thread_ID);else//创建写者线程h_Thread[i]=CreateThread(NULL,0,\(LPTHREAD_START_ROUTINE)(R_WriterThread),\&thread_info[i],0,&thread_ID);}wait_for_all=WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1);cout<<"所有的读者和写者线程完成操作."<<endl;}//读者优先-----读者线程void R_ReaderThread(void *p){//互斥变量HANDLE h_Mutex;h_Mutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_readcount");DWORD wait_for_mutex; //等待互斥变量所有权DWORD m_delay; //延迟时间DWORD m_ThreadRunTime; //读文件持续时间int m_Threadhao; //线程序号m_Threadhao=((ThreadInfo *)(p))->Threadhao;m_delay=(DWORD)(((ThreadInfo *)(p))->ThreadStartTime*100);m_ThreadRunTime=(DWORD)(((ThreadInfo *)(p))->ThreadRunTime*100);Sleep(m_delay); //延迟等待cout<<"读者线程"<<m_Threadhao<<" 发出读请求."<<endl;//等待互斥对象通知wait_for_mutex=WaitForSingleObject(h_Mutex,-1); //等待互斥信号,保证对readcount的访问、//修改互斥readcount++; //读者数目加一if (readcount==1)EnterCriticalSection(&RP_Write);//禁止写者进入ReleaseMutex(h_Mutex);//释放互斥对象,允许下个读者继续读://读文件cout<<"读者线程"<<m_Threadhao<<" 开始读文件."<<endl;Sleep(m_ThreadRunTime);//退出线程cout<<"读者线程"<<m_Threadhao<<" 完成读文件."<<endl;wait_for_mutex=WaitForSingleObject(h_Mutex,-1); //等待互斥信号,保证对readcount的访问、修改互斥readcount--; //读者数目减少if (readcount==0)LeaveCriticalSection(&RP_Write); //如果所有读者读完,唤醒写者ReleaseMutex(h_Mutex);//释放互斥信号}//读者优先-----写者线程void R_WriterThread(void *p){DWORD m_delay; //延迟时间DWORD m_ThreadRunTime; //读文件持续时间int m_Threadhao; //线程序号//从参数中获得信息m_Threadhao=((ThreadInfo *)(p))->Threadhao;m_delay=(DWORD)(((ThreadInfo *)(p))->ThreadStartTime*100);m_ThreadRunTime=(DWORD)(((ThreadInfo *)(p))->ThreadRunTime*100);Sleep(m_delay); //延迟等待cout<<"写者线程"<<m_Threadhao<<" 发出写请求."<<endl;EnterCriticalSection(&RP_Write);//禁止下一位写者进入//写文件cout<<"写者线程"<<m_Threadhao<<" 开始写文件."<<endl;Sleep(m_ThreadRunTime);//退出线程cout<<"写者线程"<<m_Threadhao<<" 完成写文件."<<endl;LeaveCriticalSection(&RP_Write); //如果所有读者读完,唤醒写者}//写者优先处理函数void WriterFun(char* file){DWORD n_thread=0; //线程数目DWORD thread_ID; //线程IDDWORD wait_for_all; //等待所有线程结束//互斥对象HANDLE h_Mutex1, h_Mutex2, h_Mutex3;h_Mutex1 = CreateMutex(NULL, FALSE, "mutex_for_writecount");h_Mutex2 = CreateMutex(NULL, FALSE, "mutex_for_readcount");h_Mutex3 = CreateMutex(NULL, FALSE, "mutex_for_read");//线程对象数组HANDLE h_Thread[64];ThreadInfo thread_info[64];readcount=0; //初始化readcountInitializeCriticalSection(&cs_Write); //初始化临界区InitializeCriticalSection(&cs_Read);ifstream inFile;inFile.open(file); //打开文件cout<<"写者优先:\n"<<endl;while (inFile){//读入每一个读者、写者的信息inFile>>thread_info[n_thread].Threadhao>>thread_info[n_thread].ThreadClass>>thread_info[n_thread].ThreadStartTime>>thread_info[n_thread].ThreadRunTime;if(-1 == inFile.get())break;n_thread++;//线程数加一}for (int i=0;i<(int)(n_thread);i++){if (thread_info[i].ThreadClass=='r')//创建读者线程h_Thread[i]=CreateThread(NULL,0,\(LPTHREAD_START_ROUTINE)(W_ReaderThread),\&thread_info[i],0,&thread_ID);else//创建写者线程h_Thread[i]=CreateThread(NULL,0,\(LPTHREAD_START_ROUTINE)(W_WriterThread),\&thread_info[i],0,&thread_ID);}//等待所有线程结束wait_for_all=WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1);cout<<"所有的读者和写者线程完成操作."<<endl;}//写者优先-----写者线程void W_WriterThread(void *p){//互斥变量HANDLE h_Mutex1;h_Mutex1 = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_writecount");DWORD wait_for_mutex; //等待互斥变量所有权DWORD m_delay; //延迟时间DWORD m_ThreadRunTime; //读文件持时续间int m_Threadhao; //线程序号m_Threadhao=((ThreadInfo *)(p))->Threadhao;m_delay=(DWORD)(((ThreadInfo *)(p))->ThreadStartTime*100);//每秒时钟中断100次m_ThreadRunTime=(DWORD)(((ThreadInfo *)(p))->ThreadRunTime*100);Sleep(m_delay);cout<<"写者线程"<<m_Threadhao<<" 发出写请求."<<endl;wait_for_mutex=WaitForSingleObject(h_Mutex1,-1);writecount++;if (writecount==1)EnterCriticalSection(&cs_Read);ReleaseMutex(h_Mutex1);EnterCriticalSection(&cs_Write);cout<<"写者线程"<<m_Threadhao<<" 开始写文件."<<endl;Sleep(m_ThreadRunTime);cout<<"写者线程"<<m_Threadhao<<" 完成写文件."<<endl;LeaveCriticalSection(&cs_Write);wait_for_mutex=WaitForSingleObject(h_Mutex1,-1);writecount--;if(writecount == 0)LeaveCriticalSection(&cs_Read);ReleaseMutex(h_Mutex1);}//写者优先-----读者线程void W_ReaderThread(void *p){HANDLE h_Mutex2, h_Mutex3;h_Mutex2 = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_readcount");h_Mutex3 = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_read");DWORD wait_for_mutex, wait_for_mutex1;//等待互斥变量所有权DWORD m_delay; //延迟时间DWORD m_ThreadRunTime; //读文件持续时间int m_Threadhao; //线程序号m_Threadhao=((ThreadInfo *)(p))->Threadhao;m_delay=(DWORD)(((ThreadInfo *)(p))->ThreadStartTime*100);m_ThreadRunTime=(DWORD)(((ThreadInfo *)(p))->ThreadRunTime*100);Sleep(m_delay);cout<<"读者线程"<<m_Threadhao<<" 发出读请求."<<endl;wait_for_mutex1=WaitForSingleObject(h_Mutex3,-1);EnterCriticalSection(&cs_Read);LeaveCriticalSection(&cs_Read);ReleaseMutex(h_Mutex3);wait_for_mutex=WaitForSingleObject(h_Mutex2,-1);readcount++;if (readcount == 1)EnterCriticalSection(&cs_Write);ReleaseMutex(h_Mutex2);cout<<"读者线程"<<m_Threadhao<<" 开始读文件."<<endl;Sleep(m_ThreadRunTime);cout<<"读者线程"<<m_Threadhao<<" 完成读文件."<<endl;wait_for_mutex=WaitForSingleObject(h_Mutex2,-1);readcount--;if (readcount == 0)LeaveCriticalSection(&cs_Write);ReleaseMutex(h_Mutex2);}。