操作系统生产者与消费者问题实验报告

合集下载

操作系统实验三 生产者——消费者问题

操作系统实验三 生产者——消费者问题

操作系统实验三:生产者——消费者问题一、基本信息xxx 711103xx 2012年4月29日二、实验目的通过实验,掌握Windows和Linux环境下互斥锁和信号量的实现方法,加深对临界区问题和进程同步机制的理解,同时巩固利用Windows API和Pthread API进行多线程编程的方法。

三、实验内容1. 在Windows操作系统上,利用Win32 API提供的信号量机制,编写应用程序实现生产者——消费者问题。

2. 在Linux操作系统上,利用Pthread API提供的信号量机制,编写应用程序实现生产者——消费者问题。

3. 两种环境下,生产者和消费者均作为独立线程,并通过empty、full、mutex 三个信号量实现对缓冲进行插入与删除。

4. 通过打印缓冲区中的内容至屏幕,来验证应用程序的正确性。

四、实验步骤1. 创建3个信号量:Mutex、Full、Empty2. 主程序创建10个生产者线程和10个消费者线程,之后休眠一段时间3. 生产者线程中,休息一段2s后,生产一个0~10的随机数放入缓冲区里。

利用信号量Mutex产生对缓冲区使用的互斥功能,利用Empty和Full信号量来对缓冲区进行增加项4. 消费者线程中,休息4s时间后,消费一个缓冲区的数据。

利用信号量Mutex产生对缓冲区使用的互斥功能,利用Empty和Full信号量来对缓冲区进行增加项5. 主程序执行一段时间后,结束整个程序五、主要数据结构及其说明产品数量最大值const int MAX_SIZE = 10;缓冲区:int buffer[BUFFER_SIZE];int front; int rear; bool full;三个互斥信号量:HANDLE Mutex; HANDLE Full; HANDLE Empty;有关操作:用WaitForSingleSignal函数可以获得一个Mutex的所有权,类似于P 操作,而ReleaseMutex函数可以释放一个Mutex的所有权,类似于V 操作。

操作系统实验报告生产者消费者问题

操作系统实验报告生产者消费者问题

操作系统课程设计一.实验目标完成N个生产者和M个消费者线程之间的并发控制,N、M不低于30,数据发送和接收缓冲区尺寸不小于20个(每个产品占据一个)。

其中生产者线程1、3、5、7、9生产的产品供所有奇数编号的消费者线程消费,只有所有奇数编号的消费者线程都消费后,该产品才能从缓冲区中撤销。

其中生产者线程2、4、6、8、10生产的产品所有偶数编号的消费者线程都可消费,任一偶数编号消费者线程消费该消息后,该产品都可从缓冲区中撤销。

其中11-20号生产者线程生产的产品仅供对应编号的消费者线程消费。

其他编号生产者线程生产的产品可由任意的消费者线程消费。

每个生产线程生产30个消息后结束运行。

如果一个消费者线程没有对应的生产者线程在运行后,也结束运行。

所有生产者都停止生产后,如果消费者线程已经没有可供消费的产品,则也退出运行。

二.实验原理2.1原理生产者与消费者线程采用posix互斥锁机制进行互斥进入各自的代码段,只有采用互斥锁临界区代码段才可以不被打扰的执行;同步机制采用的是posix条件变量pthread_cond_wait和pthraed_cond_signal进行同步的。

线程间的通信采用的是共享内存机制。

(注:所有的共享内存块是在进程里建立的,线程只需链接上各自的共享内存块即可,每一块共享内存的大小是100). 在这里共享内存设置成一个100的数组。

具体实施:(1)为1.3.5.7.9建立一个共享内存1号,1.3.5.7.9生产者线程生产的产品都放入这块共享内存缓冲区,所有奇数的消费者线程要消费的话,只需在消费者线程中链接上这块共享内存,就可以直接消费1.3.5.7.9生产者线程生产的产品。

(2)为2.4.6.8.10建立一块共享内存2号。

2.4.6.8.10生产的产品都放入2号共享内存缓冲区,所有的偶数的消费者线程只要链接上2号缓冲区,就可以消费2.4.6.8.10生产的产品。

当偶数消费者线程消费产品后,产品即可从缓冲区撤销,方法是在消费线程里将消费的产品在共享内存数组里置0。

操作系统实验报告生产者消费者问题

操作系统实验报告生产者消费者问题

课程设计说明书山东科技大学2014年 1 月 1 日课程设计任务书一、课程设计题目:生产者消费者问题二、课程设计主要参考资料(1)《计算机操作系统》(修订版).汤子瀛.西安电子科技大学出版社。

(2)《数据结构》严蔚敏清华大学出版社(3)《操作系统概念》第六版三、课程设计应解决的主要问题:(1)了解信号量的使用(2)理解生产者消费者问题模型(3)掌握真确使用同步机制的方法(4)实现生产者消费者进程的互斥与同步四、课程设计相关附件(如:图纸、软件等):程序源代码五、任务发出日期: 2013-12-1 课程设计完成日期: 2014-12-25指导教师签字:系主任签字:指导教师对课程设计的评语成绩:指导教师签字:年月日生产者消费者问题一、设计目的1、了解信号量的使用2、加深对信号量机制的理解3、通过研究Linux 的进程机制和信号量实现生产者消费者问题的并发控制.4、掌握基本的同步互斥算法,理解生产者与消费者模型5、了解多线程(多进程)的并发执行机制,线程(进程)间的同步与互斥二、设计要求1、理解生产者与消费者问题模型,掌握解决问题的算法思想2、掌握正确使用同步机制的方法3、每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容,当前指针位置和生产者/消费者线程的标识符.4、生产者和消费者各有两个以上.5、多个生产者或多个消费者之间须有共享对缓冲区进行操作的函数代码.三、设计说明(含系统框图和(或)主要算法的流程图)生产者流程图消费者流程图有n个生产者和m个消费者,连接在具有k个单位缓冲区的有界环转缓冲上,故又称有界缓冲问题。

其中Pi 和Cj都是并发进程,只要缓冲区未满,生产者进程Pi所生产的产品就可投入缓冲区;类似地,只要缓冲区非空,消费者进程Cj就可以从缓冲区取走并消耗产品。

生产者——消费者问题是典型的进程同步问题,这些进程必须按照一定的生产率和消费率来访问共享缓冲区,用P、V操作解决生产者和消费者共享单缓冲区的问题,可设置两个信号量empty和full,其初值分别为1和0,empty指示能否向缓冲区放入产品,full 指示能否从缓冲区取出产品。

生产者消费者问题实验报告

生产者消费者问题实验报告

操作系统课程设计实验报告实验名称: 生产者消费者问题姓名/学号:一、实验目的以生产者和消费者问题为例, 学习Linux和Windows下进程通信、同步机制的具体实现方法, 主要是信号量和共享内存。

熟悉相关系统API的用法。

二、实验内容使用共享内存和信号量机制来实现多个生产者/消费者进程间的通信和同步。

要求在Linux和Windows下分别实现。

缓冲区大小为3, 初始为空。

2个生产者, 随机等待一段时间, 往缓冲区添加数据, 重复6次。

3个消费者, 重复4次。

三、实验环境Ubuntu 10.10 , GCC; Windows 7, VC 6.0;四、程序设计与实现1.Linux下:(1) 数据结构:a.共享内存定义为一个结构, 使得其数据成员更清晰且操作变得简单。

b.共享缓冲区采用循环队列的数据结构,由上面的结构struct buf { int start; int end; int info[BUF_NUM]; }维护。

其中start为队头指针, end为队尾指针, info为数据区域。

(2) 算法:a.大致由三个模块组成:i.主程序(main):ii.创建信号量、共享内存并进行初始化iii.创建生产者、消费者进程, 生产者执行pro_fun(), 消费者执行con_fun()iv.等待所有子进程的结束v.删除信号量、共享内存i.生产者进程(pro_fun):ii.通过key获得信号量、共享内存的ID, 将内存添加到自己的地址空间iii.P(empty), P(mutex), Add(data), V(mutex), V(full)iv.解除和共享内存的关联i.消费者进程(con_fun):ii.通过key获得信号量、共享内存的ID, 将内存添加到自己的地址空间iii.P(full), P(mutex), Add(data), V(mutex), V(empty)iv.解除和共享内存的关联循环队列部分:加入数据: info[end] = value; end = (end + 1) % 3;取出数据: temp = info[start]; info[start] = 0; (start = start + 1)%3; return temp;(3) 程序流程图:a.主函数:b.生产者进程:c.消费者进程和生产者类似4.Windows 下:(1) 数据结构:和Linux大致相同(2) 算法:a.创建的子进程调用正在执行的文件本身, 通过main函数的参数区分主进程和生产者、消费者进程。

操作系统生产者消费者问题实验报告

操作系统生产者消费者问题实验报告

操作系统生产者消费者问题实验报告实验名称:一、生产者-消费者问题的多线程解决方案二、设计一个执行矩阵乘法的多线程程序日期:20XX-10-22 班级:13级计科学号:姓名:一、实验目的1.掌握线程的同步与互斥2.掌握生产者消费者的实现问题3.掌握多线程的编程方法4.掌握矩阵乘法的基本计算原理以及实现二、实验内容1.生产者-消费者问题的多线程解决方案2.设计一个执行矩阵乘法的多线程程序三、项目要求与分析1.请查阅资料,掌握线程创建的相关知识以及矩阵乘法的相关知识,了解java语言程序编写的相关知识2.理解线程的实验步骤在本次试验中,以“生产者-消费者”模型为依据,提供了一个多线程的“生产者-消费者”实例,编写java代码调试运行结果,得出相应的结论。

理解矩阵乘法的实验步骤四、具体实现1.生产者-消费者实例(1)创建一个缓冲信息发送接收通道接口,并创建邮箱盒子类实现,主要代码如下://通道接口public interface Channel{public abstract void send(Object item);public abstract Object receive();}//实现接口public class MessageQueue implements Channel{private Vector queue;public MessageQueue(){queue=new Vector();}public void send(Object item){queue.addElement(ite m);}public Object receive(){if(queue.size()==0)return null;elsereturn queue.remove(0);}}(2)创建一个工厂多线程类(启动生产者和消费者),并且添加main 函数进行测试,主要代码如下://工厂类与主方法public class Factory{public Factory(){Channel mailBox=new MessageQueue();Thread producerThread=new Thread(new Producer(mailBox));Thread consumerThread=new Thread(new Consumer(mailBox));producerThread.start();consumerThread.start();}public static void main(String[] args){Factory server=new Factory();}(3)创建一个线程睡眠类,用于测试,主要代码如下:public class SleepUtilities{public static void nap(){nap(NAP_TIME);}public static void nap(int duration){int sleeptime = (int)(NAP_TIME * Math.random());try{ Thread.sleep(sleeptime*1000); }catch (InterruptedException e) {}}private static final int NAP_TIME = 5;(4)创建生产者类实现Runnable,主要代码如下:public class Producer implements Runnable{private Channel mbox;public Producer(Channel mbox){this.mbox=mbox;}public void run(){Date message;while(true){SleepUtilities.nap();message=new Date();System.out.println("Producer produced "+message);mbox.send(message);}}}(5)创建消费者类实现Runnable,主要代码如下:public class Consumer implements Runnable{private Channel mbox;public Consumer(Channel mbox){this.mbox=mbox;}public void run(){Date message;while(true){SleepUtilities.nap();message=(Date)mbox.receive();if(message!=null)System.out.println("Consumer consumed "+message);}}}(6)调试程序,运行结果:2.矩阵乘法实例(1)初始化矩阵(便于观察,这里使用随机数生成矩阵),主要初始化代码如下matrix1 = new int[m][k];matrix2 = new int[k][n];matrix3 = new int[m][n];//随机初始化矩阵a,bfillRandom(matrix1);fillRandom(matrix2);static void fillRandom(int[][] x){for (int i=0; i<x.length; i++){for(int j=0; j<x[i].length; j++){//每个元素设置为0到99的随机自然数x[i][j] = (int) (Math.random() * 100);}}}(2)打印输出矩阵函数,主要代码如下:static void printMatrix(int[][] x){for (int i=0; i<x.length; i++){for(int j=0; j<x[i].length; j++) {System.out.print(x[i][j]+" ");}System.out.println("");}System.out.println("");}(3)创建多线程类,并实现Runnable接口同步对矩阵进行分行计算,主要代码如下://创建线程,数量 <= 4for(int i=0; i<4; i++){if(index < m){Thread t = new Thread(new MyThread());t.start();}else{break;}synchronized static int getTask(){if(index < m){return index++;}return -1;}}class MyThread implements Runnable{int task;//@Overridepublic void run(){MultiThreadMatrix.threadCount++;while( (task= MultiThreadMatrix.getTask()) != -1 ){System.out.println("进程:"+Thread.currentThread().getName()+"\t开始计算第"+(task+1)+"行");for(int i=0; i<MultiThreadMatrix.n; i++){for(int j=0; j<MultiThreadMatrix.k;j++){MultiThreadMatrix.matrix3[task][i] += MultiThreadMatrix.matrix1[task][j] *MultiThreadMatrix.matrix2[j][i];}}}MultiThreadMatrix.threadCount--;}(4)通过不断改变矩阵大小,线程数目,,调试程序,运行结果:五、所遇问题与解决方法1.在生产者-消费者多线程试验中,刚开始没有考虑到使用线程睡眠,运行结果速度之快,没法观看数据变化,后面定义了睡眠控制,使得问题得以解决2.在多线程矩阵开发实验中,刚开始定义矩阵太小,测试结果不太明显,后面通过把矩阵改大,并且线程数目不断变化使得结果明显。

生产者与消费者问题实验报告

生产者与消费者问题实验报告

生产者与消费者问题实验报告生产者与消费者问题实验报告篇一:生产者和消费者问题实验报告实验报告课程名称:操作系统实验名称:生产者和消费者问题学号:学生姓名:班级:指导教师:评分:实验日期:XX年 10月 22 日篇二:操作系统实验报告经典的生产者—消费者问题实验二经典的生产者—消费者问题一、目的实现对经典的生产者—消费者问题的模拟,以便更好的理解经典进程同步问题。

二、实验内容及要求编制生产者—消费者算法,模拟一个生产者、一个消费者,共享一个缓冲池的情形。

1、实现对经典的生产者—消费者问题的模拟,以便更好的理解此经典进程同步问题。

生产者-消费者问题是典型的PV操作问题,假设系统中有一个比较大的缓冲池,生产者的任务是只要缓冲池未满就可以将生产出的产品放入其中,而消费者的任务是只要缓冲池未空就可以从缓冲池中拿走产品。

缓冲池被占用时,任何进程都不能访问。

2、每一个生产者都要把自己生产的产品放入缓冲池,每个消费者从缓冲池中取走产品消费。

在这种情况下,生产者消费者进程同步,因为只有通过互通消息才知道是否能存入产品或者取走产品。

他们之间也存在互斥,即生产者消费者必须互斥访问缓冲池,即不能有两个以上的进程同时进行。

三、生产者和消费者原理分析在同一个进程地址空间内执行两个线程。

生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。

消费者线程从缓冲区中获得物品,然后释放缓冲区。

当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放一个空缓冲区。

当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻挡,直到新的物品被生产出来。

四、生产者与消费者功能描述:生产者功能描述:在同一个进程地址空间内执行两个线程。

生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。

当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。

生产者消费者问题实验报告

生产者消费者问题实验报告

生产者消费者问题实验报告生产者消费者问题实验报告一、引言生产者消费者问题是计算机科学中一个经典的并发问题,主要涉及到多个线程之间的协作和资源的共享。

在本实验中,我们通过编写一个简单的程序来模拟生产者和消费者之间的交互过程,以深入理解该问题的本质和解决方案。

二、问题描述在生产者消费者问题中,有两类线程:生产者和消费者。

生产者线程负责生产一定数量的产品,而消费者线程则负责消费这些产品。

两类线程需要共享一个有限的缓冲区,生产者将产品放入缓冲区,而消费者从缓冲区中取出产品。

然而,缓冲区的容量是有限的,当缓冲区已满时,生产者需要等待,直到有空间可用。

同样地,当缓冲区为空时,消费者需要等待,直到有产品可用。

三、实验设计为了解决生产者消费者问题,我们采用了经典的解决方案——使用互斥锁和条件变量。

互斥锁用于保护共享资源的访问,保证同一时间只有一个线程可以访问共享资源。

而条件变量用于线程之间的通信,当某个条件不满足时,线程可以通过条件变量进入等待状态,直到条件满足时再被唤醒。

在我们的程序中,我们使用了一个有界缓冲区来模拟生产者消费者之间的交互。

缓冲区的大小可以通过参数进行设置。

我们创建了两个线程分别代表生产者和消费者,它们通过互斥锁和条件变量来实现同步。

生产者线程在缓冲区未满时将产品放入缓冲区,并通知消费者线程有产品可用;消费者线程在缓冲区非空时从缓冲区取出产品,并通知生产者线程有空间可用。

通过这种方式,我们保证了生产者和消费者之间的协作和资源的共享。

四、实验结果经过多次运行实验,我们观察到了以下现象:当生产者线程的生产速度大于消费者线程的消费速度时,缓冲区会被生产者填满,消费者需要等待;当消费者线程的消费速度大于生产者线程的生产速度时,缓冲区会被消费者清空,生产者需要等待。

只有当生产者和消费者的速度相等时,才能实现平衡的生产和消费。

此外,我们还发现在某些情况下,生产者和消费者线程可能出现死锁或饥饿现象。

死锁是指两个或多个线程相互等待对方释放资源,导致程序无法继续执行的情况。

生产消费系统实验报告(3篇)

生产消费系统实验报告(3篇)

第1篇一、实验目的1. 加深对进程概念的理解,明确进程和程序的区别。

2. 进一步认识并发执行的实质。

3. 验证用信号量机制实现进程互斥的方法。

4. 验证用信号量机制实现进程同步的方法。

二、实验环境1. 操作系统:Windows 102. 编程语言:C语言3. 开发工具:Visual Studio三、实验内容1. 生产者和消费者模型介绍生产者和消费者模型是操作系统中常见的一种并发控制模型,用于解决多个进程之间的同步和互斥问题。

在该模型中,生产者负责生成数据,消费者负责消费数据。

生产者和消费者通过共享资源(如缓冲区)进行通信。

2. 实验设计(1)环形缓冲区为了实现生产者和消费者的同步,我们设计了一个环形缓冲区,由若干个大小相等的缓冲块组成。

每个缓冲块可以容纳一个产品。

环形缓冲区的指针分别指向当前的第一个空缓冲块和第一个满缓冲块。

(2)信号量为了实现进程互斥和同步,我们使用了三个信号量:① 公用信号量:用于实现临界区互斥,初始值为1。

② 生产者私用信号量:用于实现生产者与消费者之间的同步,初始值为0。

③ 消费者私用信号量:用于实现生产者与消费者之间的同步,初始值为0。

(3)生产者进程生产者进程负责生成数据,并将数据存入环形缓冲区。

当环形缓冲区满时,生产者进程等待;当环形缓冲区有空位时,生产者进程继续生成数据。

(4)消费者进程消费者进程负责从环形缓冲区中取出数据并消费。

当环形缓冲区空时,消费者进程等待;当环形缓冲区有数据时,消费者进程继续消费数据。

3. 实验步骤(1)创建生产者进程和消费者进程。

(2)初始化信号量。

(3)运行生产者进程和消费者进程。

(4)按任意键停止程序,显示当前系统的各个参数的值。

四、实验结果与分析1. 实验结果通过运行实验程序,我们可以观察到生产者和消费者进程的运行情况。

当按下任意键停止程序时,程序将显示当前系统的各个参数的值,包括环形缓冲区的空位数量、生产者和消费者的状态等。

2. 分析(1)互斥:通过公用信号量实现生产者和消费者对环形缓冲区的互斥访问,防止了同时操作缓冲区的问题。

操作系统之进程(生产者---消费者)实验报告

操作系统之进程(生产者---消费者)实验报告

操作系统实验报告——生产者和消费者问题姓名:学号:班级:一、实验内容1、模拟操作系统中进程同步和互斥;2、实现生产者和消费者问题的算法实现;二、实验目的1、熟悉临界资源、信号量及PV操作的定义与物理意义;2、了解进程通信的方法;3、掌握进程互斥与进程同步的相关知识;4、掌握用信号量机制解决进程之间的同步与互斥问题;5、实现生产者-消费者问题,深刻理解进程同步问题;三、实验题目在Windows操作系统下用C语言实现经典同步问题:生产者—消费者,具体要求如下:(1)一个大小为10的缓冲区,初始状态为空。

(2)2个生产者,随机等待一段时间,往缓冲区中添加数据,若缓冲区已满,等待消费者取走数据之后再添加,重复10次。

页脚内容1(3)2个消费者,随机等待一段时间,从缓冲区中读取数据,若缓冲区为空,等待生产者添加数据之后再读取,重复10次。

四、思想本实验的主要目的是模拟操作系统中进程同步和互斥。

在系统进程并发执行异步推进的过程中,由于资源共享和进程间合作而造成进程间相互制约。

进程间的相互制约有两种不同的方式。

(1)间接制约。

这是由于多个进程共享同一资源(如CPU、共享输入/输出设备)而引起的,即共享资源的多个进程因系统协调使用资源而相互制约。

(2)直接制约。

只是由于进程合作中各个进程为完成同一任务而造成的,即并发进程各自的执行结果互为对方的执行条件,从而限制各个进程的执行速度。

生产者和消费者是经典的进程同步问题,在这个问题中,生产者不断的向缓冲区中写入数据,而消费者则从缓冲区中读取数据。

生产者进程和消费者对缓冲区的操作是互斥,即当前只能有一个进程对这个缓冲区进行操作,生产者进入操作缓冲区之前,先要看缓冲区是否已满,如果缓冲区已满,则它必须等待消费者进程将数据取出才能写入数据,同样的,消费者进程从缓冲区读取数据之前,也要判断缓冲区是否为空,如果为空,则必须等待生产者进程写入数据才能读取数据。

在本实验中,进程之间要进行通信来操作同一缓冲区。

操作系统生产者与消费者实验报告

操作系统生产者与消费者实验报告

实验报告第页专业_______软件工程_____ 班级_________ 学号_____ 姓名实验日期:年月日报告退发(订正、重做)课程实验名称生产者与消费者问题、读者—写者问题一、实验目的1. 实现生产者消费者问题模拟2. 进一步掌握P,V如何解决同步和互斥问题二、实验环境1. Windows或Linux平台2. Eclipse、Visual Studio 2005或GCC三、实验内容、步骤和结果分析实验内容:实现生产者消费者问题模拟,显示每次添加和读取数据时缓冲区的状态,生产者和消费者可用线程模拟。

1.一个大小为10的缓冲区,初始为空。

2. 五个生产者:若缓冲区可以加入数据,则示意进入生产过程(打印出生产者ID),往缓冲区添加数据,随机等待一段时间。

若缓冲区已满,等待消费者取走数据后再添加。

3. 五个消费者:若缓冲区可以读取数据,则示意进入消费过程(打印出消费者ID),从缓冲区读取数据,随机等待一段时间;若缓冲区为空,等待生产者添加数据后再读取。

四、讨论(说明实验过程中遇到的问题及解决办法;未解决/需进一步研讨的问题或建议新实验方法等)(请利用实验二中所给的各个版本信号量类来完成实验三。

若选用Windows平台,要求一定要选用这三个文件夹中的某个信号量类Semaphore来完成实验,否则实验报告视为缺交;若选用Linux平台,也要求参照已给出的三个版本的Semaphore类的接口,先定义一个Linux版本的C++类class Semaphore,并在该类基础上完成实验,提交实验报告时请附上自定义的Semaphore类。

读者—写者问题:#include<windows.h>#include"semaphore.h"#include"thread.h"#include<iostream>using namespace std;Semaphore rmutex(1);Semaphore wmutex(1);int count=0;unsigned int WINAPI Reader(void *p){while(TRUE){rmutex.P();count++;rmutex.V();if(count == 1)wmutex.P();cout << GetCurrentThreadId() << "reading the student's table"<<endl;rmutex.P();count--;rmutex.V();if(count == 0)wmutex.V();Sleep(rand()%1000);}}unsigned int WINAPI Writer(void *p){while(TRUE){wmutex.P();cout << GetCurrentThreadId() << "writting the student's table"<<endl;wmutex.V();Sleep(rand()%1000);}}int main(){HANDLE hThread[2];hThread[0] = startThread(Reader,NULL);hThread[1] = startThread(Writer,NULL);::WaitForMultipleObjects(2,hThread,TRUE,INFINITE);CloseHandle(hThread[0]);CloseHandle(hThread[1]);return 0;}生产者与消费者问题:#include<windows.h>#include"semaphore.h"#include"thread.h"#include<iostream>using namespace std;Semaphore full(5);Semaphore empty(5);Semaphore mutex(1);int count=0;unsigned int WINAPI Producer(void *p){while(TRUE){empty.P();mutex.P();cout << GetCurrentThreadId() << " produce!"<<endl;mutex.V();full.V();Sleep(rand()%1000);}}unsigned int WINAPI Consumer(void *p){while(TRUE){full.P();mutex.P();cout << GetCurrentThreadId() << " consum!"<<endl;mutex.V();empty.V();Sleep(rand()%1000);}}int main(){HANDLE hThread[2];hThread[0] = startThread(Producer,NULL);hThread[1] = startThread(Consumer,NULL);::WaitForMultipleObjects(2,hThread,TRUE,INFINITE);CloseHandle(hThread[0]);CloseHandle(hThread[1]); return 0;}。

四川大学操作系统课程设计第三次实验报告生产者和消费者

四川大学操作系统课程设计第三次实验报告生产者和消费者

实验报告(学生打印后提交)实验名称: 生产者和消费者问题实验时间: 2023年 5 月 5日●实验人员:●实验目的:掌握基本的同步互斥算法, 理解生产者和消费者模型。

●了解Windows 2023/XP中多线程的并发执行机制, 线程间的同步和互斥。

●学习使用Windows 2023/XP中基本的同步对象, 掌握相应的API●实验环境: WindowsXP + VC++6.0●运用Windows SDK提供的系统接口(API, 应用程序接口)完毕程序的功能。

API是操作系统提供的用来进行应用程序设计的系统功能接口。

使用API, 需要包含对API函数进行说明的SDK头文献, 最常见的就是windows.h实验环节:1.读懂源程序.2.编辑修改源程.......................................实验陈述:1.基础知识:本实验用到几个API函数:CreateThread CreateMutex, WaitForSingleObject, ReleaseMutexCreateSemaphore, WaitForSingleObject, ReleaseSemaphore, ReleaseMutex, nitializeCriticalSection, EnterCriticalSection, LeaveCriticalSection。

这些函数的作用:CreateThread, 功能:创建一个线程, 该线程在调用进程的地址空间中执行。

CreateMutex,功能:产生一个命名的或者匿名的互斥量对象。

WaitForSingleObject(相应p操作)锁上互斥锁, ReleaseMutex(相应v操作)打开互斥锁.。

CreateSemaphore, 创建一个命名的或者匿名的信号量对象。

信号量可以看作是在互斥量上的一个扩展。

WaitForSingleObject, 功能:使程序处在等待状态, 直到信号量(或互斥量)hHandle出现或者超过规定的等待最长时间, 信号量出现指信号量大于或等于1, 互斥量出现指打开互斥锁。

操作系统实验报告生产者与消费者问题模拟

操作系统实验报告生产者与消费者问题模拟

操作系统上机实验报告实验名称:生产者与消费者问题模拟实验目的:通过模拟生产者消费者问题理解进程或线程之间的同步与互斥。

实验内容:1、设计一个环形缓冲区,大小为10,生产者依次向其中写入1到20,每个缓冲区中存放一个数字,消费者从中依次读取数字。

2、相应的信号量;3、生产者和消费者可按如下两种方式之一设计;(1)设计成两个进程;(2)设计成一个进程内的两个线程。

4、根据实验结果理解信号量的工作原理,进程或线程的同步\互斥关系。

实验步骤及分析:一.管道(一)管道定义所谓管道,是指能够连接一个写进程和一个读进程的、并允许它们以生产者—消费者方式进行通信的一个共享文件,又称为pipe文件。

由写进程从管道的写入端(句柄1)将数据写入管道,而读进程则从管道的读出端(句柄0)读出数据。

(二)所涉及的系统调用1、pipe( )建立一无名管道。

系统调用格式pipe()参数定义int pipe();int [2];其中,[1]是写入端,[0]是读出端。

该函数使用头文件如下:#include <unistd.h>#inlcude <signal.h>#include <stdio.h>2、read( )系统调用格式:read(fd,buf,nbyte)功能:从fd所指示的文件中读出nbyte个字节的数据,并将它们送至由指针buf所指示的缓冲区中。

如该文件被加锁,等待,直到锁打开为止。

参数定义:int read(fd,buf,nbyte);int fd;char *buf;unsigned nbyte;3、write( )系统调用格式read(fd,buf,nbyte)功能:把nbyte 个字节的数据,从buf所指向的缓冲区写到由fd所指向的文件中。

如文件加锁,暂停写入,直至开锁。

参数定义同read( )。

(三)参考程序#include <unistd.h>#include <signal.h>#include <stdio.h>int pid1,pid2;main( ){int fd[2];char outpipe[100],inpipe[100];pipe(fd); /*创建一个管道*/while ((pid1=fork( ))==-1);if(pid1==0){lockf(fd[1],1,0);/*把串放入数组outpipe中*/sprintf(outpipe,"child 1 is using pipe!");/*向管道写长为50字节的串*/write(fd[1],outpipe,50);sleep(5); /*自我阻塞5秒*/lockf(fd[1],0,0);exit(0);}else{while((pid2=fork( ))==-1);if(pid2==0){lockf(fd[1],1,0); /*互斥*/sprintf(outpipe,"child 2 is using pipe!");write(fd[1],outpipe,50);sleep(5);lockf(fd[1],0,0);exit(0);}else{wait(0); /*同步*/read(fd[0],inpipe,50);/*从管道中读长为50字节的串*/printf("%s\n",inpipe);wait(0);read(fd[0],inpipe,50);printf("%s\n",inpipe);exit(0);}}}编写过程:运行结果:二、信号机制(一)信号的基本概念每个信号都对应一个正整数常量(称为signal number,即信号编号。

生产者-消费者操作系统实验报告

生产者-消费者操作系统实验报告

一、目的和要求在采用多道程序设计的系统中,往往有若干个进程并发执行。

进程之间存在相互制约关系,本实验模拟在单处理器情况下的进程并发执行过程中,如何利用信号量机制实现并发进程的同步和互斥,帮助学生加深了解信号量机制、进程的同步和互斥。

二、实验内容利用高级语言模拟生产者-消费者算法算法。

分析:本算法需要解决以下问题1、生产者和消费者不能同时进入缓冲池2、缓冲池已满时,生产者不能再投放3、缓冲池为空时,消费者不能消费问题解决方法1、使用互斥变量mutex,为1时,可以进入,为0不可进入,通过lock()和unlock()实现锁定和解锁2、通过数组pbuffer[n]和pnum[n]实现生产者队列,分别记录生产者的商品以及生产者序号。

生产者进程产生时判断队列是否有进程等待,当缓冲区满时,进入队列,出现空区时,队列优先进入。

3、通过数组cnum[n]实现消费者队列,用于记录消费者编号,消费者进程产生时判断队列是否有进程等待,当缓冲区空时,进入队列,出现非空时,队列优先进入。

三、算法设计与实现主流程图示:生产者功能流程图示:消费者功能流程图示:实验函数void main();void run();void jiance(int mutex);//判断当前缓冲区是否被占用void lock(int mutex);//将缓冲池锁定mutex置为1void unlock(int mutex);//释放缓冲池mutex置为0void producer();//生产者进程int pro();//生产者随机生产的产品int pisempty();//判断生产者队列是否为空int bisempty();//判断缓冲池的各个缓冲区是否都已经被填满void input(int pn,int nextp);//在生产者队列为空的条件下,进行放入缓冲池的操作void input2();//生产者队列不为空时,排队进入缓冲池void inpb(int pn,int nextp);//生产者队列为空时进入生产者队列void customer();//消费者进程int cisempty();//判断消费者队列是否为空void outb(int cn);//消费者队列为空时,进入消费者队列void output2();//消费者队列不为空时,排队消费产品void output(int cn);//取出缓冲池商品,进行消费的操作四、运行界面。

操作系统实验报告-生产者与消费者

操作系统实验报告-生产者与消费者

中南大学操作系统实验报告实验内容:Java多线程模拟生产者消费者问题实验时间:2014年5月指导老师:胡小龙老师姓名:代巍班级:信安1201班学号:**********一、实验目的对操作系统的整体进行一个模拟,通过实践加深对各个部分的管理功能的认识,还能进一步分析各个部分之间的联系,最后达到对完整系统的理解。

可以提高运用操作系统知识解决实际问题的能力;锻炼实际的编程能力,要达到以下要求。

(1)掌握进程(线程)的同步与互斥。

(2)掌握生产者消费者问题的实现方法。

(3)掌握多线程编程方法。

二、实验内容实现生产者消费者问题。

(1)假设循环缓冲队列共有多个缓冲单元。

(2)生产者线程的工作:生产出一个产品(即产生一个产品编号),按顺序往缓冲队列中“空”的缓冲单元放产品。

(3)消费者线程与的工作:从缓冲队列装有产品的缓冲单元中取出一个产品(即产品编号)。

(4)保证两个线程间的互斥和同步(5)在界面上打印缓冲队列的变化情况三、实验原理(1)生产者—消费者问题是一种同步问题的抽象描述。

(2)计算机系统中的每个进程都可以消费或生产某类资源。

当系统中某一进程使用某一资源时,可以看作是消耗,且该进程称为消费者。

(3)而当某个进程释放资源时,则它就相当一个生产者。

模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介。

生产者把数据放入缓冲区,而消费者从缓冲区取出数据。

大概的结构如下图。

四、实验思想概述在操作系统中,线程有时被称为轻量级进程,是CPU使用的基本单位,它与属于同一进程的其他进程共享其他代码段、数据段和其他操作系统资源。

在Java中,线程的建立有两种方法:继承Thread类和实现Runnable接口。

其中,采用实现Runnable接口建立线程的好处是允许同时继承其他类从而实现多继承,并且在Java中,可采用synchronized或Object类的方法wait(),notify(),notifyAll()来实现多线程同步。

操作系统实验报告生产者与消费者算法实现

操作系统实验报告生产者与消费者算法实现

目录实验一生产者-消费者 (2)一、设计思想描述 (2)二、生产者与消费者实现代码 (2)三、实验结果 (5)四、心得体会 (5)实验二进程调度模拟程序 (6)一、实验设计思想 (6)二、算法中用到的数据结构 (7)三、实验代码 (8)四、实验结果 (14)五、结果分析 (15)六、实验总结 (15)实验三银行家算法 (16)一、设计思想 (16)二、算法描述及数据结构模型 (16)三、数据结构 (17)四、源代码 (17)五、程序运行结果及分析 (23)实验四内存管理模拟系统 (25)一、设计思想 (25)二、算法用到的主要数据结构 (25)三、模块调试 (27)四、测试结果 (31)实验一生产者-消费者一、设计思想描述3.1生产者功能描述在同一个进程地址空间内执行的两个线程。

生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。

当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。

3.2消费者功能描述消费者线程从缓冲区中获得物品,然后释放缓冲区。

当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。

3.3程序结构图:二、生产者与消费者实现代码#include <windows.h>#include <iostream>const unsigned short SIZE_OF_BUFFER = 10; //缓冲区长度unsigned short ProductID = 0; //产品号unsigned short ConsumeID = 0; //将被消耗的产品号unsigned short in = 0; //产品进缓冲区时的缓冲区下标unsigned short out = 0; //产品出缓冲区时的缓冲区下标int g_buffer[SIZE_OF_BUFFER]; //缓冲区是个循环队列bool g_continue = true; //控制程序结束HANDLE g_hMutex; //用于线程间的互斥HANDLE g_hFullSemaphore; //当缓冲区满时迫使生产者等待HANDLE g_hEmptySemaphore; //当缓冲区空时迫使消费者等待DWORD WINAPI Producer(LPVOID); //生产者线程DWORD WINAPI Consumer(LPVOID); //消费者线程int main(){//创建各个互斥信号g_hMutex = CreateMutex(NULL,FALSE,NULL);g_hFullSemaphore = CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1,NULL);g_hEmptySemaphore = CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL);//调整下面的数值,可以发现,当生产者个数多于消费者个数时,//生产速度快,生产者经常等待消费者;反之,消费者经常等待const unsigned short PRODUCERS_COUNT = 3; //生产者的个数const unsigned short CONSUMERS_COUNT = 1; //消费者的个数//总的线程数const unsigned short THREADS_COUNT = PRODUCERS_COUNT+CONSUMERS_COUNT;HANDLE hThreads[PRODUCERS_COUNT]; //各线程的handleDWORD producerID[CONSUMERS_COUNT]; //生产者线程的标识符DWORD consumerID[THREADS_COUNT]; //消费者线程的标识符//创建生产者线程for (int i=0;i<PRODUCERS_COUNT;++i){hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]);if (hThreads[i]==NULL) return -1;}//创建消费者线程for (i=0;i<CONSUMERS_COUNT;++i){hThreads[PRODUCERS_COUNT+i]=CreateThread(NULL,0,Consumer,NULL,0,&consumerID[i]);if (hThreads[i]==NULL) return -1;}while(g_continue){if(getchar()){ //按回车后终止程序运行g_continue = false;}}return 0;}//生产一个产品。

操作系统实验报告-三大经典问题之生产者及消费者问题

操作系统实验报告-三大经典问题之生产者及消费者问题

计算机操作系统实验报告题目三大经典问题之生产者与消费者问题一、课程设计的性质与任务1、加深对并发协作进程同步与互斥概念的理解。

通过编写程序实现进程同步和互斥,使学生掌握有关进程(线程)同步与互斥的原理,以及解决进程(线程)同步和互斥的算法,从而进一步巩固进程(线程)同步和互斥等有关的容。

2、掌握进程和线程的概念,进程(线程)的控制原语或系统调用的使用。

3、了解Windows2000/XP中多线程的并发执行机制,线程间的同步和互斥。

学习使用Windows2000/XP中基本的同步对象,掌握相应的API函数。

4、培养学生能够独立进行知识综合,独立开发较大程序的能力。

5、培养提高学生软件开发能力和软件的调试技术。

6、培养学生开发大型程序的方法和相互合作的精神。

7、培养学生的创新意识。

8、培养学生的算法设计和算法分析能力。

9、培养学生对问题进行文字论述和文字表达的能力。

二、课程设计的容及其要求在Windows XP、Windows2000等操作系统下,使用的VC、VB、Java或C等编程语言,采用进程(线程)同步和互斥的技术编写程序实现生产者消费者问题或哲学家进餐问题或读者-写者问题或自己设计一个简单进程(线程)同步和互斥的实际问题。

要求:(1)经调试后程序能够正常运行。

(2)采用多进程或多线程方式运行,体现了进程(线程)同步互斥的关系。

(3)程序界面美观。

三、实验原理本实验要求利用PV操作实现解决生产者——消费者问题中的同步问题。

此问题描述的是一群生产者进程在生产产品并将这些产品提供给消费者进程去消费,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者进程将它所生产的产品放入一个缓冲区,消费者进程可从缓冲区中取走产品去消费,但它们之间必须保持同步,即不允许消费者进程到一个空缓冲区去取产品,也不允许生产者进程向一个已装满且尚未取出的缓冲区中投放产品,并且生产者消费者互斥使用缓冲区。

四、实验原理图五、算法实现(1)有一个生产者线程ProduceThread,有1个消费者进程CustomerThread;缓冲区为shareList。

生产者和消费者问题实验报告

生产者和消费者问题实验报告

格式: V。IDEnterCriticalSection( LPCRITICAL_SECTI。NIpCnticalSection ); LeaveCriticalSection的用法 功能:释放指定临界区对象的所有权。 格式: V。IDLeaveCriticalSection( LPCRITICAL.SECTI。NIpCriticalSection ); 2)程序结构 MI-I和序结构图 3)数据结构 (1)用一个整型数组Buffer-Critical来代表缓冲区。不管是生产产品还是对已有产品的消费都
Fer(inti-∙zi<R.reqvestHunU∙∙)
n_tħrei。.re<∣ι>tst[1]-((Thread!i⅞Fφ∙)(p))->thre⅛d.reqvest(1];
$10,P(LSl刊);
F∙r(l-∙U<R..req<∣p⅝tHuAU*∙)<
printfCXoo⅞uι⅞erVdrequesttoconς∣>aeVdpro^uct∖n-t∙-serlil.n_thr^a<l_requ«Mlt_for_sefuiphorPVanFarSinglp。bject(b_S^Mphor»(ii_thrp^d_reqiiest[i])v*-1);
文件G)⅛M∙Z)2«(X)收就")工具(D隅船。i) r^i∙-。CAftφct∙taisg4S∙S∖n<s∖Mmm6lr∙t0tA4面3f⅞文件夹∖*JfFl 文件和文件关任务 J创建一个新文件夹 θ将这个文件英宣布到 WHtb H共享,及伴英 IT*+6Y。rkSP∙c∙ Urn C*÷Ssιrc∙6KB Un VV忖Inttllistns 25KB 10簪巷

操作系统生产者消费者问题实验报告

操作系统生产者消费者问题实验报告

实验报实验名称:一、生产者•消费者问题的多线程解决方案二、设计一个执行矩阵乘法的多线程程序 ___________日期:2015・10・22班级:13级计科学号:姓名:一、实验目的1. 掌握线程的同步与互斥2. 掌握生产者消费者的实现问题3. 掌握多线程的编程方法4. 掌握矩阵乘法的基本计算原理以及实现二、实验内容1. 生产者■消费者问题的多线程解决方案2设计一个执行矩阵乘法的多线程程序三、项目要求与分析1 •请查阅资料,掌握线程创建的相尖知识以及矩阵乘法的相尖知识,了解2・ java语言程序编写的相尖知识理解线程的实验步骤在本次试验中,以“生产者■消费者”模型为依据,提供了一个多线程的码调试生产者■消费者”实例,编写java代运行结果,得岀相应的结论。

理解矩阵乘法的实验步骤四、具体实现1.生产者•消费者实例(1) 创建一个缓冲信息发送接收通道接口,并创建邮箱盒子类实现,主要代码如下://通道接口public in terface Channel{publicabstractvoid send(Object item );publicabstract Objectreceive();}//实现接口publicclass MessageQueue implements Channel {private Vector queue ;public MessageQueue() queue =n ewVectorQ;}publicvoid send(Object item){queue .addElement(ite mt}public Objectreceive() if ( queue ・size()==0) return null;elsecon (3) public staticvoid n ap() n ap(NAP_TIME);publicstaticvoidn ap( int du rati on ) int sleeptime =( int)( NAP_TIME*Math. random ());try {Thread, sleep (sleeptime *1000);} catch (InterruptedException e){}}privatestaticfi nali nt NAP_TIME=5;创建生产者类实现Runnable '主要代码如下: public classreturn queue .remove(O);}创建一个工厂多线程类(启动生产者和消费者),并且添加 main 函数进行测试,主要代码如下: //工厂类与主方法publicclass Factory{public Factory 。

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

《操作系统》实验报告生产者和消费者的问题一、实验目的1.掌握基本的同步与互斥的算法,理解基本的生产者与消费者的模型。

2.学习使用Windows 2000/XP中基本的同步对象,掌握相关的API的使用方法。

3.了解Windows 2000/XP中多线程的并发执行机制,线程间的同步和互斥。

二、实验的内容及其要求1.实验内容以生产者/消费者模型为根据,在Windows 2000环境下创建一个控制台进程,在改进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。

2.实验要求①学习并理解生产者/消费者模型及其同步/互斥规则②学习了解Windows同步对象及其特性③熟悉实验环境,掌握相关API的使用方法④设计程序,实现生产者/消费者进程(线程)的同步与互斥⑤提交实验报告三、实验的时间安排1.实验前,先到图书馆或上网百度了解有关生产者/消费者模型的相关知识,建立生产者/消费者模型的基本概念。

2.利用13周、15周、17周的上机时间编写和调试程序代码。

3.利用其他课余时间来分析实验的最终结果并完成相关的实验报告。

四、实验的环境1.硬件条件:普通计算机一台2.软件条件:①操作系统:Windows 2000/XP②开发语言:VC++本实验是在Windows 2000+VC6.0环境下实现的,利用Windows SDK提供的系统接口(API)完成程序的功能。

实验在Windows下安装VC后进行,因为VC是一个集成开发环境,其中包含了Windows SDK所有工具和定义,所以安装了VC后就不用特意安装SDK了。

实验中所用的API(应用程序接口),是操作系统提供的用来进行应用程序设计的系统功能接口。

要使用这些API,需要包含对这些函数进行说明的SDK 头文件,最常见的就是windows.h。

一些特殊的API调用还需要包含其他的头文件。

五、正文1.程序结构图:2.数据结构:(1)用一个整型数组Buffer_Critical来代表缓冲区。

不管是生产产品还是对已有产品的消费都需要访问改组缓冲区。

(2)在程序中用一个自定义结构ThreadInfo记录一条线程的信息,即将测试用例文件中的一行信息记录下来,用于程序创建相应的生产者或者消费者。

由于要创建多个线程,所以程序中使用了一个ThreadInfo结构的数组Thread_Info。

(3)在实现本程序的消费生产模型时,具体地通过如下同步对象实现互斥:●设一个互斥量h_mutex,以实现生产者在查询和保留缓冲区内的下一个空位置时进行互斥。

●每一个生产者用一个信号量与其消费者同步,通过设置h_Semaphore[MAX_THREAD_NUM]信号量数组实现,该组信号量用于表示相应产品已生产。

同时用一个表示空缓冲区数目的信号量empty_semaphore进行类似的同步,指示缓冲区中是否存在空位置,以便开始生产下一个产品。

●每一个缓冲区用一个同步对象实现该缓冲区上消费者之间的互斥,这通过设置临界区对象数组PC_Critical[MAX_BUFFER_NUM]实现。

3.实验步骤:(1)打开VC,选择菜单项File->New,选择Projects选项卡并建立一个名为R_WP1的win32 console application工程,创建时注意指定创建该工程的目录。

(2)在工程中创建源文件R_WP1.cpp:选择菜单项Project->Add to project->Files,此时将打开一个新窗口,在其中的“文件名”输入栏中输入自己想要创建的文件名,这里是R_WP1.cpp;接着询问是否创建新文件时回答“yes”。

通过Workspace->Source Files打开该文件,在其中编辑源文件并保存。

(3)通过调用菜单项Build->Rebuild all进行编译连接,可以在指定的工程目录下得到debug->R_WP1.exe 程序,然后把给定的test.txt文件存入该debug目录下,就可以在控制台进入该debug目录运行程序了。

需要强调的是:在创建数据文件时,由于涉及文件的格式问题,最好在记事本中手工逐个输入数据,而不要用复制和粘贴数据。

4.实验源代码://*************************R_WP1.cpp***************************#include<windows.h>#include<fstream.h>#include<stdio.h>#include<string>#include<conio.h>//定义一些常量//本程序允许的最大临界区数#define MAX_BUFFER_NUM 10//秒到微秒的乘法因子#define INTE_PER_SEC 1000//本程序允许的生产和消费线程的总数#define MAX_THREAD_NUM 64//定义一个结构,记录在测试文件中指定的每一个线程的参数struct ThreadInfo{int serial;char entity;double delay;int thread_request[MAX_THREAD_NUM];int n_request;};CRITICAL_SECTION PC_Critical[MAX_BUFFER_NUM];int Buffer_Critical[MAX_BUFFER_NUM];HANDLE h_Thread[MAX_BUFFER_NUM];ThreadInfo Thread_Info[MAX_THREAD_NUM];HANDLE empty_semaphore;HANDLE h_mutex;DWORD n_Thread=0;DWORD n_Buffer_or_Critical;HANDLE h_Semaphore[MAX_THREAD_NUM];void Produce(void *p);void Consume(void *p);bool IfInOtherRequest(int);int FindProducePosition();int FindBufferPositon(int);int main(void){DWORD wait_for_all;ifstream inFile;for(int i=0;i<MAX_THREAD_NUM;i++)Buffer_Critical[i]=-1;for(int j=0;j<MAX_THREAD_NUM;j++){for(int k=0;k<MAX_THREAD_NUM;k++)Thread_Info[j].thread_request[k]=-1;Thread_Info[j].n_request=0;}for(i=0;i<MAX_BUFFER_NUM;i++)InitializeCriticalSection(&PC_Critical[i]);inFile.open("d:\\test.txt");inFile>>n_Buffer_or_Critical;inFile.get();printf("输出文件是:\n");printf("%d\n",(int)n_Buffer_or_Critical);while(inFile){inFile>>Thread_Info[n_Thread].serial;inFile>>Thread_Info[n_Thread].entity;inFile>>Thread_Info[n_Thread].delay;char c;inFile.get(c);while(c!='\n'&&!inFile.eof()){inFile>>Thread_Info[n_Thread].thread_request[Thread_Info[n_Thread].n_request++];inFile.get(c);}n_Thread++;}for(j=0;j<(int)n_Thread;j++){int Temp_serial=Thread_Info[j].serial;char Temp_entity=Thread_Info[j].entity;double Temp_delay=Thread_Info[j].delay;printf("\n thread%2d %c %f",Temp_serial,Temp_entity,Temp_delay);int Temp_request=Thread_Info[j].n_request;for(int k=0;k<Temp_request;k++)printf("%d",Thread_Info[j].thread_request[k]);cout<<endl;}printf("\n\n");empty_semaphore=CreateSemaphore (NULL,n_Buffer_or_Critical,n_Buffer_or_Critical, "semaphore_for_empty");h_mutex=CreateMutex(NULL,FALSE,"mutex_for_update");for(j=0;j<(int)n_Thread;j++){std::string lp="semaphore_for_produce_";int temp=j;while(temp){char c=(char)(temp%10);lp+=c;temp/=10;}h_Semaphore[j+1]=CreateSemaphore(NULL,0,n_Thread,lp.c_str());}for(i=0;i<(int)n_Thread;i++){if(Thread_Info[i].entity=='P')h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Produce),&(Thread_Info[i]),0,NULL);elseh_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Consume),&(Thread_Info[i]),0,NULL);}wait_for_all=WaitForMultipleObjects(n_Thread,h_Thread,TRUE,-1);printf("Press any key to quit!\n");_getch();return 0;}bool IfInOtherRequest(int req){for(int i=0;i<n_Thread;i++)for(int j=0;j<Thread_Info[i].n_request;j++)if(Thread_Info[i].thread_request[j]==req)return TRUE;return FALSE;}int FindProducePosition(){int EmptyPosition;for(int i=0;i<n_Buffer_or_Critical;i++)if(Buffer_Critical[i]==-1){EmptyPosition=i;Buffer_Critical[i]=-2;break;}return EmptyPosition;}int FindBufferPosition(int ProPos){int TempPos;for(int i=0;i<n_Buffer_or_Critical;i++)if(Buffer_Critical[i]=ProPos){TempPos=i;break;}return TempPos;}void Produce(void *p){DWORD wait_for_semaphore,wait_for_mutex,m_delay;int m_serial;m_serial=((ThreadInfo*)(p))->serial;m_delay=( DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);Sleep(m_delay);printf("Producer %2d sends the produce require.\n",m_serial);wait_for_semaphore=WaitForSingleObject(h_mutex,-1);int ProducePos=FindProducePosition();ReleaseMutex(h_mutex);printf("Producer %2d begin to produce at position %2d.\n",m_serial,ProducePos);Buffer_Critical[ProducePos]=m_serial;printf("Producer %2d finish producing :\n",m_serial);printf("position[%2d]:%3d\n",ProducePos,Buffer_Critical[ProducePos]);ReleaseSemaphore(h_Semaphore[m_serial],n_Thread,NULL);}void Consume(void *p){DWORD wait_for_semaphore,m_delay;int m_serial,m_requestNum;int m_thread_request[MAX_THREAD_NUM];m_serial=((ThreadInfo*)(p))->serial;m_delay=(DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);m_requestNum=((ThreadInfo*)(p))->n_request;for(int i=0;i<m_requestNum;i++)m_thread_request[i]=((ThreadInfo*)(p))->thread_request[i];Sleep(m_delay);for(i=0;i<m_requestNum;i++){printf("Consumer %2d request to consumer %2d product\n",m_serial,m_thread_request[i]); wait_for_semaphore=WaitForSingleObject(h_Semaphore[m_thread_request[i]],-1);int BufferPos=FindBufferPosition(m_thread_request[i]);EnterCriticalSection(&PC_Critical[BufferPos]);printf("Comsumer %2d begin to consume %2d product \n",m_serial,m_thread_request[i]);((ThreadInfo*)(p))->thread_request[i]=-1;if(!IfInOtherRequest(m_thread_request[i])){Buffer_Critical[BufferPos]=-1;printf("position [%2d]:%3d\n",BufferPos,Buffer_Critical[BufferPos]);ReleaseSemaphore(empty_semaphore,1,NULL);}else{printf("Consumer %2d finish consuming product %2d\n",m_serial,m_thread_request[i]); }LeaveCriticalSection(&PC_Critical[BufferPos]);}}5.实验运行结果:其中的实验数据是:31 p 52 p 43 p 24 c 3 1 3 26.实验结果分析:(1)在每个程序中需要先做P,后做V,二者要成对出现,夹在二者中间的代码段就是该进程的临界区。

相关文档
最新文档