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

电子科技大学计算机学院实验中心小心计算机专业类课程实验报告课程名称:操作系统学 院:软件学院专 业:软件工程学生姓名:李 希学 号: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,并成功的对子进程进行了调度与管理。
操作系统课程设计报告——读者写者问题

操作系统课程设计课题:读者写者问题姓名:赫前进班级:1020552学号102055211指导教师:叶瑶提交时间:2012/12/30(一)实验目的1.进一步理解“临界资源”的概念;2.把握在多个进程并发执行过程中对临界资源访问时的必要约束条件;3.理解操作系统原理中“互斥”和“同步”的涵义。
(二)实验内容利用程序设计语言编程,模拟并发执行进程的同步与互斥(要求:进程数目不少于3 个)。
(三)、程序分析读者写者问题的定义如下:有一个许多进程共享的数据区,这个数据区可以是一个文件或者主存的一块空间;有一些只读取这个数据区的进程(Reader)和一些只往数据区写数据的进程(Writer),此外还需要满足以下条件:(1)任意多个读进程可以同时读这个文件;(2)一次只有一个写进程可以往文件中写;(3)如果一个写进程正在进行操作,禁止任何读进程度文件。
实验要求用信号量来实现读者写者问题的调度算法。
实验提供了signal类,该类通过P( )、V( )两个方法实现了P、V原语的功能。
实验的任务是修改Creat_Writer()添加写者进程,Creat_Reader()创建读者进程。
Reader_goon()读者进程运行函数。
读优先:要求指一个读者试图进行读操作时,如果这时正有其他读者在进行操作,他可直接开始读操作,而不需要等待。
读者优先的附加限制:如果一个读者申请进行读操作时已有另一读者正在进行读操作,则该读者可直接开始读操作。
写优先:一个读者试图进行读操作时,如果有其他写者在等待进行写操作或正在进行写操作,他要等待该写者完成写操作后才开始读操作。
写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。
在Windows 7 环境下,创建一个控制台进程,此进程包含n 个线程。
用这n 个线程来表示n 个读者或写者。
每个线程按相应测试数据文件(格式见下)的要求进行读写操作。
操作系统实验报告--华科

实验一哲学家就餐问题一、实验目的1、熟练使用VC++6.0编译环境,调试并正确运行程序。
2、理解哲学家就餐问题中出现的问题,进而掌握死锁的必要条件。
3、理解源程序中产生和防止死锁的算法,及相关窗口操作。
4、熟悉哲学家就餐问题流程。
5、在VC++6.0环境下编译哲学家就餐问题演示程序,考虑其他解决死锁方法.二、实验原理1、问题描述有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,每两人之间放一只筷子。
每个哲学家的行为是思考,感到饥饿,然后吃通心粉。
为了吃通心粉,每个哲学家必须拿到两只筷子,并且每个人只能直接从自己的左边或右边去取筷子。
2、分配方式方式一(不会进入死锁)仅当一个哲学家左右两边的筷子都可用时,才允许他拿筷子。
这样要么一次占有两只筷子(所有线程需要的资源)进行下一步的吃通心粉,然后释放所有的资源;要么不占用资源,这样就不可能产生死锁了。
方式二(会进入死锁)当筷子(资源)可用时,先分配左边的筷子,等待一会后再分配右边的筷子,由于这个过程中,左边的筷子一直没有释放,就有可能产生死锁了。
3、程序运行说明程序运行过程中会弹出一个MessageBox提示操作者操作:1)第一个对话框用于选择运行模式a.选择yes 表示采用的是运行的防止死锁的方式,这样的话整个程序可以一直运行下去,不会产生死锁。
b.选择no 表示运行产生死锁的方式会弹出第二个对话框。
2)第二个对话框用于选择运行时,线程运行的时间a. 选择res 线程时间比较短,很快就可以死锁b.选择no 线程时间跟选择yes 时候的时间差不多,产生死锁的时间稍微长一点。
三、实验过程及分析1、伪代码:1) 不发生死锁的方式(要么一下占用两支筷子,要么不占用)var mutexleftchopstick,mutexrightchopstick;beging:resting;waiting;p(mutexleftchopstick); //先改变左手筷子信号量p(mutexrightchopstick); //马上改变右手筷子信号量GetResource(leftchopstick,rightchopstick);eating;v(mutexleftchopstick);v(mutexrightchopstick);end2) 发生死锁的方式(一旦可以占用筷子,就马上占用)var mutexleftchopstick,mutexrightchopstick;beging:resting;waiting;p(mutexleftchopstick); //改变左手筷子信号量GetResource(leftchopstick); //获取左手筷子p(mutexrightchopstick); //改变右手筷子信号量GetResource(rightchopstick); //获取右手筷子eating;v(mutexleftchopstick);v(mutexrightchopstick);end2、代码分析:1)不发生死锁的方式:先确定两只筷子均没被占用才获取筷子,这样就打破了死锁的必要条件。
操作系统实验报告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:学号:012081034课程设计进程同步模拟设计——读者和题目写者问题学院计算机科学与技术学院专业计算机科学与技术班级计算机科学与技术姓名指导教师2011 年 1 月19 日目录目录 (1)1 设计概述 (4)1.1问题描述: (4)1.1.1规则: (4)1.1.2读者和写者的相互关系: (4)1.2采用信号量机制 (4)1.3 C++语言程序模拟用信号量机制实现生产者和消费者问题 (5)2课程设计目的及功能 (5)2.1 设计目的 (5)2.2 设计功能: (5)3 需求分析,数据结构或模块说明(功能与框图) (5)3.1数据结构 (5)3.2模块说明 (6)3.3开发平台及源程序的主要部分 (6)3.3.1写操作的设计: (6)3.3.2读操作的设计: (7)3.3.3主函数的设计: (9)3.4 功能流程图 (12)4测试用例,运行结果与运行情况分析 (12)4.1测试用例 (12)4.2运行结果 (13)4.3运行情况分析 (14)5自我评价与总结 (15)6 参考文献 (16)课程设计任务书学生姓名:专业班级:计算机科学与技术指导教师:工作单位:计算机科学与技术学院题目: 进程同步模拟设计——读者和写者问题初始条件:1.预备内容:阅读操作系统的进程管理章节内容,对进程的同步和互斥,以及信号量机制度有深入的理解。
2.实践准备:掌握一种计算机高级语言的使用。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.模拟用信号量机制实现读者和写者问题。
2.设计报告内容应说明:⑴课程设计目的与功能;⑵需求分析,数据结构或模块说明(功能与框图);⑶源程序的主要部分;⑷测试用例,运行结果与运行情况分析;⑸自我评价与总结:i)你认为你完成的设计哪些地方做得比较好或比较出色;ii)什么地方做得不太好,以后如何改正;iii)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);iv)完成本题是否有其他的其他方法(如果有,简要说明该方法);v)对实验题的评价和改进意见,请你推荐设计题目。
寄存器的读取与写入操作实验

寄存器的读取与写入操作实验寄存器是计算机中的重要组成部分,用于存储和处理数据。
在计算机系统中,有许多寄存器,每个寄存器都有特定的用途和功能。
本文将重点探讨寄存器的读取和写入操作的实验过程和注意事项。
一、实验目的本实验旨在通过实际操作,了解寄存器的读取和写入操作的过程,并掌握相关的方法和技巧。
通过实验可以加深对寄存器的理解,提高对计算机硬件的认知。
二、实验材料与设备1. 计算机硬件设备:主机、键盘、显示器等。
2. 实验软件:任选一款编程软件,如汇编语言仿真器等。
三、实验步骤1. 准备工作:a. 打开计算机,并确保硬件设备正常运行。
b. 载入所选的编程软件,并准备进行编程操作。
2. 读取寄存器:a. 在编程软件中,选择要读取的寄存器。
b. 编写相应的代码,用于读取寄存器中的数据。
c. 运行代码,并观察寄存器中的数据是否被成功读取。
3. 写入寄存器:a. 在编程软件中,选择要写入的寄存器。
b. 编写相应的代码,用于向寄存器中写入数据。
c. 运行代码,并检查数据是否成功写入寄存器。
4. 实验数据记录与分析:a. 记录读取和写入寄存器的代码和过程。
b. 分析实验结果,观察是否有错误或异常情况。
c. 总结寄存器读取和写入操作的注意事项和技巧。
四、实验注意事项1. 确保实验环境安全,避免因操作不当导致的硬件损坏。
2. 编写代码时,注意语法和格式的正确性,避免出现编译错误。
3. 在编程过程中,仔细检查代码逻辑,避免出现数据错误或意外情况。
4. 在实验过程中,及时保存和备份相关数据和代码,以防数据丢失。
五、实验结果与分析经过实验操作,我们成功读取和写入了寄存器中的数据。
通过观察实验结果,我们可以清楚地了解寄存器的读取和写入操作的步骤和方法。
同时,我们还可以根据实验数据进行进一步的分析和研究,以提高对寄存器的理解和应用能力。
六、实验总结通过本次寄存器的读取与写入操作实验,我们对寄存器的功能和使用方法有了更深入的了解。
共享内存及实验(读者写者问题)
Linux课程设计报告专业班级:学号:姓名:Linux共享内存通信的原理分析及实验(读者写者问题)一、原理说明及分析1:共享内存的相关原理1)共享内存就是内存中一个区域(段)的映射,这个区域可以被更多的进程所共享。
它是IPC机制中最快的一种形式,因为它不需要中间环节,而是直接把信息从一个内存段映射到调用进程的地址空间。
因为进程可以直接读写内存,而不需要任何数据的拷贝。
对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次数据:一次从输入文件到共享内存区,另一次从共享内存区到输出文件。
实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,再重新建立共享内存区域。
而是保持共享区域,直到通信完毕为止,这样,数据内容一直保存在共享内存中,并没有写回文件。
共享内存中的内容往往是在解除映射时才写回文件的。
因此,采用共享内存的通信方式效率是非常高的。
2)一个段可以直接由一个进程创建,随后可以有任意多个进程对其进读和写。
但是,一旦内存被共享之后,对共享内存的访问同步需要由其他的IPC机制,例如信号量来实现。
Linux对共享内存的存取控制是通过对访问键和访问权限的检查来控制的。
2:mmap()及相关系统调用1)mmap()系统调用使得进程之间通过映射同一个普通文件实现共享内存。
普通文件被映射到进程地址空间后,进程可以向访问普通内存一样对文件进行访问,不必再调用read(),write()等操作。
mmap()系统调用形式如下:void* mmap ( void * addr , size_t len , int prot , int flags , int fd , off_t offset )例如:p_map=(people*)mmap(NULL,sizeof(people),PROT_READ|PROT_WRITE,MAP_SHARE|MAP_ANONYMOUS,-1,0);2)系统调用mmap()用于共享内存有两种方式:a)使用普通文件提供的内存映射:适用于任何进程之间;此时,需要打开或创建一个文件,然后再调用mmap();典型调用代码如下:fd=open(name, flag, mode);if(fd<0)...ptr=mmap(NULL, len , PROT_READ|PROT_WRITE, MAP_SHARED , fd , 0);b)使用特殊文件提供匿名内存映射:适用于具有亲缘关系的进程之间;由于父子进程特殊的亲缘关系,在父进程中先调用mmap(),然后调用fork()。
读者-写者问题解答计算机操作系统实验报告指导资料
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)读者优先的设计思想是读进程只要看到有其它读进程正在读,就可以继续进行读;写进程必须等待所有读进程都不读时才能写,即使写进程可能比一些读进程更早提出申请。
读写者实验报告
《Linux系统分析》实验报告报告提交日期:姓名:程志超学号: 128355003 班级:交换生一、实验题目采用多线程互斥与同步机制,实现读者、写者问题二、实验目的掌握使用POSIX接口提供的互斥变量、条件变量实现多线程同步三、实验要求有一个文件为多个并发线程所共享,其中读线程只要求读取文件内容,写线程则要求修改文件容,允许多个线程同时读取文件内容。
但若有一个写线程在写,则其他读线程不能读;若有一个写线程在写或有其他读线程在读,则其他写线程均被拒绝。
当一个写线程正在写,而有多个读线程与写线程在等待时,写线程应优先唤醒。
读线程进去读、等待,写线程进去写、等待等状态均在屏幕上打印出来四、设计思路和流程图(对于涉及算法的实验,需要提供数据结构及其说明、测试数据的设计及测试结果分析)数据结构的说明struct prodcons{int buffer[BUFFERSIZE]; //缓冲区pthread_mutex_t lock; //互斥锁int readpos,writepos; //读写的游标pthread_cond_t notempty; //缓冲区非空条件判断pthread_cond_t notfull; //缓冲区非满条件判断};测试结果:读和写的线程交互进行五、实验体会(包括实验中遇到的问题及解决过程、产生的错误及原因分析)对线程条件变量控制相关函数pthread_cond_init()、pthread_cond_wait()和pthread_cond_signal()的原型及用法不是很了解,上网查阅相关资料,明白第一个是初始化一个条件变量,第二个等待线程,尤其要注意线程状态和条件变量的加解锁过程是/*block-->unlock-->wait() return-->lock*/六、程序清单(包括源程序、makefile、readme)/***multithread.c***/#include<stdio.h>#include<pthread.h>#define BUFFERSIZE 100#define OVER (-1)struct prodcons{int buffer[BUFFERSIZE];pthread_mutex_t lock;int readpos,writepos;pthread_cond_t notempty;pthread_cond_t notfull;};void init(struct prodcons *b){pthread_mutex_init(&b->lock,NULL);pthread_cond_init(&b->notempty,NULL);pthread_cond_init(&b->notfull,NULL);b->readpos = 0;b->writepos = 0;}void put(struct prodcons *b,int data){pthread_mutex_lock(&b->lock);if((b->writepos + 1) % BUFFERSIZE == b->readpos){ pthread_cond_wait(&b->notfull,&b->lock);}b->buffer[b->writepos] = data;b->writepos++;if(b->writepos >= BUFFERSIZE)b->writepos = 0;pthread_cond_signal(&b->notempty);pthread_mutex_unlock(&b->lock);}int get(struct prodcons *b){int data;pthread_mutex_lock(&b->lock);if(b->writepos == b->readpos){pthread_cond_wait(&b->notempty,&b->lock);}data = b->buffer[b->readpos];b->readpos++;if(b->readpos >= BUFFERSIZE)b->readpos = 0;pthread_cond_signal(&b->notfull);pthread_mutex_unlock(&b->lock);return data;}struct prodcons buffer;void *producer1(void *data){int n;for(n = 0;n < 10000;n++){//printf("%d\n",n);printf("producer1 is writing\n");put(&buffer,n);}put(&buffer,OVER);return NULL;}void *producer2(void *data){int n;for(n = 0;n < 10000;n++){//printf("%d\n",n);printf("producer2 is writing\n");put(&buffer,n);}put(&buffer,OVER);return NULL;}void *consumer1(void * data){int d;while(1){d = get(&buffer);if(d == OVER)break;//printf("%d\n",d);printf("consumer1 is reading\n");}return NULL;}void *consumer2(void * data){int d;while(1){d = get(&buffer);if(d == OVER)break;//printf("%d\n",d);printf("consumer2 is reading\n");}return NULL;}int main(void){pthread_t writer1,reader1,writer2,reader2;void *retval;init(&buffer);pthread_create(&writer1,NULL,producer1,0);pthread_create(&reader1,NULL,consumer1,0);pthread_create(&writer2,NULL,producer2,0);pthread_create(&reader2,NULL,consumer2,0);pthread_join(writer1,&retval);pthread_join(reader1,&retval);pthread_join(writer2,&retval);pthread_join(reader2,&retval);return 0;}。
读写者问题
设计一读者写者问题实习环境:系统为Windows XP + VC 6.0一、实验目的:1、加深对进程概念的理解,明确进程和程序的区别,进一步认识并发执行的实质;2、理解和运用信号量、PV原语、进程间的同步互斥关系等基本知识。
二、设计要求在Windows XP下创建一个控制台进程,该进程应包含n个线程。
用这n个线程来表示n个读者或写者。
每个线程按相应测试数据文件(后面介绍)的要求进行读写操作。
用信号量机制分别实现读者优先和写者优先的读者-写者问题。
读者-写者问题的操作限制(包括读者优先和写者优先):1)写-写互斥,即不能有两个写者同时进行写操作。
2)读-写互斥,即不能同时有一个线程在读,而另一个线程在写。
3)读-读互斥,即可以有一个或多个读者在读。
读者优先的附加限制:如果一个读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。
写者优先的附加限制:如果一个读者申请进行读操作时已有另一个写者在等待访问共享资源,则该读者必须等到没有写者出于等待状态后才能开始读操作。
测试文件格式说明,下面是一个测试数据文件的例子:1 R 3 52 W 4 53 R 5 24 R 6 55 W 5.1 36 R 15 47 R 15 4三、设计说明1、读者优先指除非有写者在写文件,否则读者不需要等待。
所以可以用一个整形变量readnum记录当前的读者数目,用于确定是否需要唤醒正在等待的写者进程(当readnum==读者人数时,表明所有的读者读完,需要唤醒写者等待队列中的第一个写者)。
每一个读者开始读文件时,必须修改readnum变量。
因此需要一个互斥对象rnum[]来实现对全局变量readnum修改时的互斥。
另外,为了实现写写互斥,需要增加一个临界区对象wstate。
当写者发出写请求时,必须申请临界区对象的所有权。
通过这种方法,也可以实现读写互斥,当readnum=2时(即第一个读者到来时),读者进程也必须申请临界区对象的所有权。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
操作系统实验报告
实验名称:读入者和写入者问题
院系:电子与信息工程系 班级:电信 学号: 姓名:
一、 实验目的 1.理解互斥与临界区的含义 2熟练使用 VC++6.0 或者codeblock编译环境,调试并正确运行程序。 3.理解阅读者和写入者中出现的问题,进而掌握信号量的使用。 4.理解源程序中管理阅读者和写入者权限的算法,及相关窗口操作。
二、实验原理
1、问题描述:有一个公用的数据集,有很多人需要访问,其中一些需要阅读其中的信息,一些需要修改其中的消息。阅读者可以同时访问数据集,而写入者只能互斥的访问数据集,不能与任何的进程一起访问数据区。 2、源程序算法实现调度说明:程序中,实现读者优先的原则,即当有读者等待时,优先使读者读消息,等到读者阅读完成后再进行写入操作(不可同时读出和写入,但可以同时多用户读出)。当同时又写入和读出等待时,同样先执行读出操作。 3、程序运行说明: 1)本程序主要用于说明阅读者写入者问题中的资源互斥访问的调动策略,并模仿其访问的过程。采用书上的伪码编制而成,实际上采用的是读优先策略。 2)在本程序中用于表现的图形界面说明:在程序编译运行后会出现中间一个大的圆圈表示公用的资源,上面一排五个矩形表示 5 个读者,下面的五个矩形表示五个写入者。每个读者和写入者都有 3 种状态,休息,等待和操作(读入或者写入)分别用黑颜色,绿颜色,红颜色表示休息,等待和操作。一旦操作者获得资源,可以进行读或者写,我们就划一条从操作者中心到资源中心的线,表示开始操作。
三.实验内容 及分析 要求:允许多个阅读者同时对文件进行操作;只允许一个写入者执行写入操作;任何写入者对文件进行写入操作时不允许任何其他写入者或者阅读者操作;阅读者执行阅读操作时写入者无法写入。 单纯使用信号量无法解决以上互斥问题必须引入计数器readcount对读进程计数mutex时对计数器操作的互斥信号量,writeblock时能否写入的信号量。 初始化设置都是处于休息状态,然后要是资源可读,根据进程到来的快慢,分配资源给读者,是其从休息,等待到读状态,最后释放资源进入休息状态,一直循环。一旦有一个读者进入临界区,我们就封锁临界区,可以让所用的读者进入,而不让写入者进入,并用一个资源控制readercount,保证每次只有一个进程对变量进行操作。这样,直到每一个读者都读完,没有一个读者的时候,开始释放临界区,这样写入者就可以进入与读者进行资源的争夺,决定是读还是写。
伪代码: Intreadcount=0; Semaphore writeblock,mutex; Writeblock=1;mutex=1;//初始条件可以写入读入 Cobegin Process reader_i(){ P(mutex)//获取进入临界区权限 Readcound++;//阅读者人数加一 If(readcount==1)//阅读者人数等于一表示之前没有人阅读,需要获取阅读权限 P(writeblock)//写入者无法写入 V(mutex)//释放权限,允许其他阅读者进入 /*读文件*/ P(mutex)//阅读完毕获取修改阅读人数的权限 Readcount--;//阅读人数减一 If(readcount==0)/*表示他是最后一个阅读者,代表阅读者释放临界区,允许写入者写入*/ V(writeblock); V(mutex); } end Process writer_i(){ //写入进程
P(writeblock);//写入者写入,阅读者无法进入临界区 /*写数据集;*/ V(writeblock);//开放写入 end
} Coend 1.本程序主要用于说明阅读者写入者问题中的资源互斥访问的调动策略,并模仿其访问的过程。采用书上的伪码编制而成,实际上采用的是读优先策略。 2.在本程序中用于表现的图形界面说明:在程序编译运行后会出现中间一个大的圆圈表示公用的资源,上面一排五个矩形表示5个读者,下面的五个矩形表示五个写入者。每个读者和写入者都有3种状态,休息,等待和操作(读入或者写入)分别用黑颜色,绿颜色,红颜色表示休息,等待和操作。一旦操作者获得资源,可以进行读或者写,我们就划一条从操作者中心到资源中心的线,表示开始操作。
四.实验小结 虽然实验原理比较简单,也相较于容易理解,但是说实话,代码量较大,函数与较多,我独自完成实在有些难,我做到水平基本上也只是看懂了参考代码。也学会了几个函数的用法,对图形界面有了简单的了解。如果不是图显示,用文字描述真有些让人头痛。图像既形象又生动。 这里使用的是阅读者优先算法,同时也会有写入者优先算法,但是单独的阅读者优先或者写入者优先算法都不算太完善,难免会有不足之处,而以后在写设计算法的过程中,我们要逐渐学会考虑到对用户的友好性,使阅读者或写入者优先算法交替使用,从而获得最好效果。 这次试验同时大量的变量的处理,全局的统筹,是我之前所没有的尝试过的,也是一次巨大的突破,虽然做的不怎么好,自己做的时候无法同时关注众多的变量,常常出很多bug,老是考虑不周。做了两个实验了,效果还是甚微。我觉得看了那么,虽然能看懂一些,但是自己动手还是差了好多。以后要多练练。要有全局观。 附录(代码) #define WIN32_LEAN_AND_MEAN #include #include #include #include #include "MtVerify.h" #include "ReaderAndWriter.h"
int PASCAL WinMain(HINSTANCE, HINSTANCE, LPSTR, int); BOOL InitApplication(HINSTANCE); BOOL InitInstance(HINSTANCE, int);
extern HWND hWndMain; // Main Window Handle
#define P_DELAY rand()/25*10 intReadercount; //the number of reader intreaderstate[CCounter]; //the state of reader intwriterstate[CCounter]; //the state of writer intresourcestate[CCounter]; //the state of resource CRITICAL_SECTION RP_Write; //the variable used to identify the Critical Section HANDLE count; //the resouce used to define the readcount #undefPostMessage #define PostMessageSendMessage
DWORD WINAPI ReaderThread(LPVOID pVoid) { intReaderNum = (int) pVoid; // get the number of thread(reader) DWORD result; //Randomize the random number generator srand( (unsigned)time( NULL ) * (ReaderNum + 1) ); readerstate[ReaderNum] = resting; //reader is resting Sleep(P_DELAY); for(;;) {// Wait until resources are available readerstate[ReaderNum] = waiting; //reader is waiting PostMessage(hWndMain, WM_FORCE_REPAINT,0 ,0); result=WaitForSingleObject(count, INFINITE); //get the resource of count if(result==WAIT_OBJECT_0) Readercount+=1; if(Readercount==1) EnterCriticalSection(&RP_Write); //get the critical section MTVERIFY(ReleaseMutex(count)); // release the resource of count resourcestate[ReaderNum] = read; readerstate[ReaderNum] = reading; //the reader is reading PostMessage(hWndMain, WM_FORCE_REPAINT,0 ,0); Sleep(P_DELAY/4);
result=WaitForSingleObject(count, INFINITE); //get the resource of count if(result==WAIT_OBJECT_0) Readercount-=1; if(Readercount==0) LeaveCriticalSection(&RP_Write); //leave the cristical section MTVERIFY(ReleaseMutex(count)); //release the resource of count readerstate[ReaderNum] = resting; //the reader is reading resourcestate[ReaderNum] = UNUSED; PostMessage(hWndMain, WM_FORCE_REPAINT,0 ,0); Sleep(P_DELAY); } return 0; } DWORD WINAPI WriterThread(LPVOID pVoid) { intwriterNum = (int)pVoid; // get the nunber of thread(writer) //Randomize the random number generator srand( (unsigned)time( NULL ) * (writerNum + 1) ); writerstate[writerNum] = resting; //the writer id resting Sleep(P_DELAY); for(;;) { // Wait until resources are available writerstate[writerNum] = waiting; //the writer is waiting PostMessage(hWndMain, WM_FORCE_REPAINT,0 ,0); EnterCriticalSection(&RP_Write); // enter the critical section writerstate[writerNum] = writing; // the writer is writing resourcestate[writerNum] = write; PostMessage(hWndMain, WM_FORCE_REPAINT,0 ,0); Sleep(P_DELAY/4); LeaveCriticalSection(&RP_Write); //leave the critical section