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

合集下载

生产者消费者问题实践报告问题建议

生产者消费者问题实践报告问题建议

生产者消费者问题实践报告问题建议下载提示:该文档是本店铺精心编制而成的,希望大家下载后,能够帮助大家解决实际问题。

文档下载后可定制修改,请根据实际需要进行调整和使用,谢谢!本店铺为大家提供各种类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by this editor. I hope that after you download it, it can help you solve practical problems. The document can be customized and modified after downloading, please adjust and use it according to actual needs, thank you! In addition, this shop provides you with various types of practical materials, such as educational essays, diary appreciation, sentence excerpts, ancient poems, classic articles, topic composition, work summary, word parsing, copy excerpts, other materials and so on, want to know different data formats and writing methods, please pay attention!生产者消费者问题实践报告问题建议1. 引言生产者消费者问题是计算机科学中经典的并发问题之一,涉及多线程环境下的数据共享与同步。

生产者消费者实验报告

生产者消费者实验报告

生产者消费者实验报告生产者消费者实验报告引言:生产者消费者模型是计算机科学中的一个经典问题,用于解决多线程并发访问共享资源的同步问题。

在本实验中,我们通过编写一个简单的Java程序来模拟生产者消费者模型,并观察其运行结果和效果。

一、实验背景生产者消费者模型是一种常见的并发模型,用于解决多线程访问共享资源时可能出现的数据竞争和同步问题。

在该模型中,生产者负责生产数据并将其放入共享缓冲区,而消费者则负责从缓冲区中取出数据进行消费。

为了确保生产者和消费者之间的同步与互斥,需要使用合适的同步机制,如信号量、互斥锁等。

二、实验目的本实验的主要目的是通过编写一个简单的生产者消费者程序,验证该模型在多线程环境下的正确性和效果。

我们将通过观察程序的输出结果和运行时间来评估其性能,并分析其中可能存在的问题和改进空间。

三、实验设计1. 编写生产者类和消费者类:我们首先定义了一个共享缓冲区,用于存储生产者生产的数据。

然后,我们编写了一个生产者类和一个消费者类,分别实现了生产者和消费者的逻辑。

在生产者类中,我们使用了一个循环来模拟生产者不断地生产数据,并将其放入缓冲区。

而在消费者类中,我们同样使用了一个循环来模拟消费者不断地从缓冲区中取出数据进行消费。

2. 同步机制的选择:为了保证生产者和消费者之间的同步与互斥,我们选择了信号量作为同步机制。

在生产者类中,我们使用一个信号量来控制缓冲区的可用空间,当缓冲区已满时,生产者将等待,直到有可用空间。

而在消费者类中,我们同样使用一个信号量来控制缓冲区的可用数据,当缓冲区为空时,消费者将等待,直到有可用数据。

3. 实验参数的设置:为了模拟真实的生产者消费者场景,我们设置了以下参数:- 缓冲区大小:10- 生产者数量:3- 每个生产者生产的数据量:1000- 消费者数量:2四、实验结果与分析在运行实验程序后,我们观察到以下结果:1. 生产者和消费者之间的同步与互斥得到了有效保证,生产者在缓冲区已满时会等待,直到有可用空间;消费者在缓冲区为空时会等待,直到有可用数据。

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

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

《操作系统》实验报告生产者和消费者的问题一、实验目的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来代表缓冲区。

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

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

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

理解矩阵乘法的实验步骤四、具体实现1.生产者-消费者实例(1)创建一个缓冲信息发送接收通道接口,并创建邮箱盒子类实现,主要代码如下://通道接口public interface Channelpublic 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(newProducer(mailBox));Thread consumerThread=new Thread(newConsumer(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.在多线程矩阵开发实验中,刚开始定义矩阵太小,测试结果不太明显,后面通过把矩阵改大,并且线程数目不断变化使得结果明显。

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

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

河北建筑工程学院实验报告年月日班级物联121姓名连龙学号2012326134评分实验台号同组人员实验名称生产者消费者问题实验课程名称操作系统仪器名称型号规格仪器编号PC机Window XP或Windows 7一、实验目的理解生产者消费者问题,理解生产者产生任务进入缓存或队列排队等待处理,消费者在队列等待或进行任务处理的过程二、实验设备PC 机三、实验内容在java开发环境下模拟经典进程同步问题,生产者——消费者问题。

四、程序主要代码import java.awt.*;import javax.swing.*;import javax.swing.border.TitledBorder;import java.awt.event.*;public class abc extends JFrame implements ActionListener{static abc frm=new abc();static JButton bun1=new JButton("生产者1");static JButton bun2=new JButton("生产者2");static JButton bun3=new JButton("生产者3");static JButton bun4=new JButton("消费者1");static JButton bun5=new JButton("消费者2");static JButton bun6=new JButton("消费者3");static JTextField jt1 = new JTextField(" ");static JTextField jt2 = new JTextField(" ");static JTextField jt3 = new JTextField(" ");static JTextField jt4 = new JTextField(" ");static JTextField jt5 = new JTextField(" ");static JTextField jt6 = new JTextField(" ");static JTextField jt7 = new JTextField(" "); static JTextField jt8 = new JTextField(" ");public static void main(String[] args) {frm.setLayout(null);frm.setSize(800,450);frm.setLocation(500,300);bun1.addActionListener(frm);bun2.addActionListener(frm);bun3.addActionListener(frm);bun4.addActionListener(frm);bun5.addActionListener(frm);bun6.addActionListener(frm);bun1.setSize(80,40);bun1.setLocation(60,325);frm.add(bun1);bun2.setSize(80,40);bun2.setLocation(170,325);frm.add(bun2);bun3.setSize(80,40);bun3.setLocation(280,325);frm.add(bun3);bun4.setSize(80,40);bun4.setLocation(400,325);frm.add(bun4);bun5.setSize(80,40);bun5.setLocation(510,325);frm.add(bun5);bun6.setSize(80,40);bun6.setLocation(620,325);frm.add(bun6);jt1.setSize(80,40);jt1.setLocation(400,200);frm.add(jt1);jt2.setSize(80,40);jt2.setLocation(280,200);frm.add(jt2);jt3.setSize(80,40);jt3.setLocation(60,95);frm.add(jt3);jt4.setSize(80,40);jt4.setLocation(170,95);frm.add(jt4);jt5.setSize(80,40);jt5.setLocation(280,95);frm.add(jt5);jt6.setSize(80,40);jt6.setLocation(400,95);frm.add(jt6);jt7.setSize(80,40);jt7.setLocation(510,95);frm.add(jt7);jt8.setSize(80,40);jt8.setLocation(620,95);frm.add(jt8);frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frm.setVisible(true);}public void actionPerformed(ActionEvent e){JButton bun=(JButton)e.getSource();if(bun==bun1){if(jt6.getText().equals(" ")){if(jt1.getText().equals(" ")){jt1.setText(bun1.getText());}else if(jt2.getText().equals(" ")){jt2.setText(bun1.getText());}else if(jt3.getText().equals(" ")){jt3.setText(bun1.getText());bun1.setEnabled(false);}else if(jt4.getText().equals(" ")){jt4.setText(bun1.getText());bun1.setEnabled(false);}else if(jt5.getText().equals(" ")){jt5.setText(bun1.getText());bun1.setEnabled(false);}}else{if(jt7.getText().equals(" ")){jt6.setText(" ");bun4.setEnabled(true);bun5.setEnabled(true);bun6.setEnabled(true);}else if(jt8.getText().equals(" ")){jt6.setText(jt7.getText());jt7.setText(" ");if(jt6.getText().equals("消费者1")) {bun4.setEnabled(false);bun5.setEnabled(true);bun6.setEnabled(true);}else if(jt6.getText().equals("消费者2")) {bun4.setEnabled(true);bun5.setEnabled(false);bun6.setEnabled(true);}else{bun4.setEnabled(true);bun5.setEnabled(true);bun6.setEnabled(false);}}else{if(jt6.getText().equals("消费者1")) {bun4.setEnabled(true);bun5.setEnabled(false);bun6.setEnabled(false);}else if(jt6.getText().equals("消费者2")) {bun4.setEnabled(false);bun5.setEnabled(true);bun6.setEnabled(false);}else{bun4.setEnabled(false);bun5.setEnabled(false);bun6.setEnabled(true);}jt6.setText(jt7.getText());jt7.setText(jt8.getText());jt8.setText(" ");}}}else if(bun==bun2){if(jt6.getText().equals(" ")){if(jt1.getText().equals(" ")){jt1.setText(bun2.getText());}else if(jt2.getText().equals(" ")){jt2.setText(bun2.getText());}else if(jt3.getText().equals(" ")){jt3.setText(bun2.getText());bun2.setEnabled(false);}else if(jt4.getText().equals(" ")){jt4.setText(bun2.getText());bun2.setEnabled(false);}else if(jt5.getText().equals(" ")){jt5.setText(bun2.getText());bun2.setEnabled(false);}}else{if(jt7.getText().equals(" ")){jt6.setText(" ");bun4.setEnabled(true);bun5.setEnabled(true);bun6.setEnabled(true);}else if(jt8.getText().equals(" ")){jt6.setText(jt7.getText());jt7.setText(" ");if(jt6.getText().equals("消费者1")) {bun4.setEnabled(false);bun5.setEnabled(true);bun6.setEnabled(true);}else if(jt6.getText().equals("消费者2")) {bun4.setEnabled(true);bun5.setEnabled(false);bun6.setEnabled(true);}else{bun4.setEnabled(true);bun5.setEnabled(true);bun6.setEnabled(false);}}else{if(jt6.getText().equals("消费者1")) {bun4.setEnabled(true);bun5.setEnabled(false);bun6.setEnabled(false);}else if(jt6.getText().equals("消费者2")) {bun4.setEnabled(false);bun5.setEnabled(true);bun6.setEnabled(false);}else{bun4.setEnabled(false);bun5.setEnabled(false);bun6.setEnabled(true);}jt6.setText(jt7.getText());jt7.setText(jt8.getText());jt8.setText(" ");}}}else if(bun==bun3){ if(jt6.getText().equals(" ")){if(jt1.getText().equals(" ")){jt1.setText(bun3.getText());}else if(jt2.getText().equals(" ")){jt2.setText(bun3.getText());}else if(jt3.getText().equals(" ")){jt3.setText(bun3.getText());bun3.setEnabled(false);}else if(jt4.getText().equals(" ")){jt4.setText(bun3.getText());bun3.setEnabled(false);}else if(jt5.getText().equals(" ")){jt5.setText(bun3.getText());bun3.setEnabled(false);}}else{if(jt7.getText().equals(" ")){jt6.setText(" ");bun4.setEnabled(true);bun5.setEnabled(true);bun6.setEnabled(true);}else if(jt8.getText().equals(" ")){jt6.setText(jt7.getText());jt7.setText(" ");if(jt6.getText().equals("消费者1")) {bun4.setEnabled(false);bun5.setEnabled(true);bun6.setEnabled(true);}else if(jt6.getText().equals("消费者2")) {bun4.setEnabled(true);bun5.setEnabled(false);bun6.setEnabled(true);}else{bun4.setEnabled(true);bun5.setEnabled(true);bun6.setEnabled(false);}}else{if(jt6.getText().equals("消费者1")){bun4.setEnabled(true);bun5.setEnabled(false);bun6.setEnabled(false);}else if(jt6.getText().equals("消费者2")){bun4.setEnabled(false);bun5.setEnabled(true);bun6.setEnabled(false);}else{bun4.setEnabled(false);bun5.setEnabled(false);bun6.setEnabled(true);}jt6.setText(jt7.getText());jt7.setText(jt8.getText());jt8.setText(" ");}}}else if(bun==bun4){ if(jt1.getText().equals(" ")){if(jt6.getText().equals(" ")){jt6.setText(bun4.getText());bun4.setEnabled(false);}else if(jt7.getText().equals(" ")){jt7.setText(bun4.getText());bun4.setEnabled(false);}else if(jt8.getText().equals(" ")){jt8.setText(bun4.getText());bun4.setEnabled(false);}}elseif(jt2.getText().equals(" ")){jt1.setText(" ");}else if(jt3.getText().equals(" ")&jt4.getText().equals(" ")&jt5.getText().equals(" ")){ jt1.setText(jt2.getText());jt2.setText(" ");}else if(jt4.getText().equals(" ")&jt5.getText().equals(" ")){jt1.setText(jt2.getText());jt2.setText(jt3.getText());jt3.setText(" ");bun1.setEnabled(true);bun2.setEnabled(true);bun3.setEnabled(true);}else if(jt5.getText().equals(" ")){jt1.setText(jt2.getText());jt2.setText(jt3.getText());jt3.setText(jt4.getText());jt4.setText(" ");if(jt3.getText().equals("生产者1")) {bun1.setEnabled(false);bun2.setEnabled(true);bun3.setEnabled(true);}else if(jt3.getText().equals("生产者2")) {bun1.setEnabled(true);bun2.setEnabled(false);bun3.setEnabled(true);}else{bun1.setEnabled(true);bun2.setEnabled(true);bun3.setEnabled(false);}}else{jt1.setText(jt2.getText());jt2.setText(jt3.getText());jt3.setText(jt4.getText());jt4.setText(jt5.getText());jt5.setText(" ");if(jt2.getText().equals("生产者1")) {bun1.setEnabled(true);bun2.setEnabled(false);bun3.setEnabled(false);}else if(jt2.getText().equals("生产者2")) {bun1.setEnabled(false);bun2.setEnabled(true);bun3.setEnabled(false);}else{bun1.setEnabled(false);bun2.setEnabled(false);bun3.setEnabled(true);}}}else if(bun==bun5){ if(jt1.getText().equals(" ")){if(jt6.getText().equals(" ")){jt6.setText(bun5.getText());bun5.setEnabled(false);}else if(jt7.getText().equals(" ")){jt7.setText(bun5.getText());bun5.setEnabled(false);}else if(jt8.getText().equals(" ")){jt8.setText(bun5.getText());bun5.setEnabled(false);}}elseif(jt2.getText().equals(" ")){jt1.setText(" ");}else if(jt3.getText().equals(" ")&jt4.getText().equals(" ")&jt5.getText().equals(" ")){ jt1.setText(jt2.getText());jt2.setText(" ");}else if(jt4.getText().equals(" ")&jt5.getText().equals(" ")){jt1.setText(jt2.getText());jt2.setText(jt3.getText());jt3.setText(" ");bun1.setEnabled(true);bun2.setEnabled(true);bun3.setEnabled(true);}else if(jt5.getText().equals(" ")){jt1.setText(jt2.getText());jt2.setText(jt3.getText());jt3.setText(jt4.getText());jt4.setText(" ");if(jt3.getText().equals("生产者1")){bun1.setEnabled(false);bun2.setEnabled(true);bun3.setEnabled(true);}else if(jt3.getText().equals("生产者2")){bun1.setEnabled(true);bun2.setEnabled(false);bun3.setEnabled(true);}else{bun1.setEnabled(true);bun2.setEnabled(true);bun3.setEnabled(false);}}else{jt1.setText(jt2.getText());jt2.setText(jt3.getText());jt3.setText(jt4.getText());jt4.setText(jt5.getText());jt5.setText(" ");if(jt2.getText().equals("生产者1")){bun1.setEnabled(true);bun2.setEnabled(false);bun3.setEnabled(false);}else if(jt2.getText().equals("生产者2")){bun1.setEnabled(false);bun2.setEnabled(true);bun3.setEnabled(false);}else{bun1.setEnabled(false);bun2.setEnabled(false);bun3.setEnabled(true);}}}else if(bun==bun6){ if(jt1.getText().equals(" ")){if(jt6.getText().equals(" ")){jt6.setText(bun6.getText());bun6.setEnabled(false);}else if(jt7.getText().equals(" ")){jt7.setText(bun6.getText());bun6.setEnabled(false);}else if(jt8.getText().equals(" ")){jt8.setText(bun6.getText());bun6.setEnabled(false);}}elseif(jt2.getText().equals(" ")){jt1.setText(" ");}else if(jt3.getText().equals(" ")&jt4.getText().equals(" ")&jt5.getText().equals(" ")){ jt1.setText(jt2.getText());jt2.setText(" ");}else if(jt4.getText().equals(" ")&jt5.getText().equals(" ")) {jt1.setText(jt2.getText());jt2.setText(jt3.getText());jt3.setText(" ");bun1.setEnabled(true);bun2.setEnabled(true);bun3.setEnabled(true);}else if(jt5.getText().equals(" ")){jt1.setText(jt2.getText());jt2.setText(jt3.getText());jt3.setText(jt4.getText());jt4.setText(" ");if(jt3.getText().equals("生产者1")){bun1.setEnabled(false);bun2.setEnabled(true);bun3.setEnabled(true);}else if(jt3.getText().equals("生产者2")){bun1.setEnabled(true);bun2.setEnabled(false);bun3.setEnabled(true);}else{bun1.setEnabled(true);bun2.setEnabled(true);bun3.setEnabled(false);}}else{jt1.setText(jt2.getText());jt2.setText(jt3.getText());jt3.setText(jt4.getText());jt4.setText(jt5.getText());jt5.setText(" ");if(jt2.getText().equals("生产者1")){bun1.setEnabled(true);bun2.setEnabled(false);bun3.setEnabled(false);}else if(jt2.getText().equals("生产者2")){bun1.setEnabled(false);bun2.setEnabled(true);bun3.setEnabled(false);}else{bun1.setEnabled(false);bun2.setEnabled(false);bun3.setEnabled(true);}}}}}五、实验结果运行程序,显示如下:。

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

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

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

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

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

•提示本实验的主要目的是模拟操作系统中进程同步和互斥。

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

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

(1)间接制约。

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

(2)直接制约。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

消费者功能描述:消费者线程从缓冲区获得物品,然后释放缓冲区,当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。

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

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

操作系统生产者消费者问题实验报告实验名称:一、生产者-消费者问题的多线程解决方案二、设计一个执行矩阵乘法的多线程程序日期: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.在多线程矩阵开发实验中,刚开始定义矩阵太小,测试结果不太明显,后面通过把矩阵改大,并且线程数目不断变化使得结果明显。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

(3)程序界面美观。

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

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

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

生产消费系统实验报告(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.进一步认识并发执行的实质。

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

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

【实验要求】用c语言编程搭建“生产者和消费者”经典进程通信问题的环境。

要求程序运行时,按任意键停止,显示当前系统的各个参数的值。

提交实验报告,以及相关程序列表。

打包成附件上传。

【实验环境】Visual C++6.0【实验内容】1.了解经典同步问题“生产者和消费者”生产者与消费者可以通过一个环形缓冲池联系起来,环形缓冲池由几个大小相等的缓冲块组成,每个缓冲块容纳一个产品。

每个生产者可不断地每次往缓冲池中送一个生产产品,而每个消费者则可不断地每次从缓冲池中取出一个产品。

指针i和指针j分别指出当前的第一个空缓冲块和第一个满缓冲块。

2.分析和理解(1)既存在合作同步问题,也存在临界区互斥问题合作同步:当缓冲池全满时,表示供过于求,生产者必须等待,同时唤醒消费者;当缓冲池全空时,表示供不应求,消费者应等待,同时唤醒生产者。

互斥:缓冲池显然是临界资源,所在生产者与消费都要使用它,而且都要改变它的状态。

(2)基于环形缓冲区的生产者与消费者关系形式描述:公用信号量mutex:初值为1,用于实现临界区互斥生产者私用信号量empty:初值为n,指示空缓冲块数目消费者私用信号量full:初值为0,指示满缓冲块数目整型量i和j初值为0,i指示首空缓冲块序号,j指示首满缓冲块序号(3)PV原语var mutex,empty,full:semaphore;i,j:integer;buffer:array[0...n-1] of item;i:=j:=1;Procedure producer;beginwhile true dobeginproduce a product;P(empty);P(mutex);buffer(i):=product;i:=(i+1) mod n;V(mutex);V(full);end;end;Procedure consumer;beginP(full);P(mutex);goods:=buffer(j);j:=(j+1) mod n;V(mutex);V(empty);consume a product;end;end;【实验源程序代码】#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,&con sumerID[i]);if (hThreads[i]==NULL) return -1;}while(g_continue){if(getchar()){ //按回车后终止程序运行g_continue = false;}}return 0;}//生产一个产品。

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

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

实验报告第页专业_______软件工程_____ 班级_________ 学号_____ 姓名实验日期:年月日报告退发(订正、重做)课程实验名称生产者与消费者问题、读者—写者问题一、实验目的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、生产者和消费者不能同时进入缓冲池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);//取出缓冲池商品,进行消费的操作四、运行界面。

生产者和消费者问题

生产者和消费者问题

班级姓名:学号:成绩:实验名称: 生产者和消费者问题1.实验目的:“生产者消费者”问题是一个著名的同时性编程问题的集合。

通过编写经典的“生产者消费者”问题的实验,读者可以进一步熟悉Linux 中多线程编程,并且掌握用信号量处理线程间的同步互斥问题。

2.实验内容:“生产者消费者”问题描述如下。

有一个有限缓冲区和两个线程:生产者和消费者。

他们分别把产品放入缓冲区和从缓冲区中拿走产品。

当一个生产者在缓冲区满时必须等待,当一个消费者在缓冲区空时也必须等待。

它们之间的关系如下图所示:这里要求用有名管道来模拟有限缓冲区,用信号量来解决生产者消费者问题中的同步和互斥问题。

3.实验方法:(1)使用信号量解决(2)思考使用条件变量解决4.实验过程(1)信号量的考虑这里使用3个信号量,其中两个信号量avail和full分别用于解决生产者和消费者线程之间的同步问题,mutex是用于这两个线程之间的互斥问题。

其中avail初始化为N(有界缓冲区的空单元数),mutex 初始化为1,full初始化为0。

/*product.c*/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <pthread.h>#include <errno.h>#include <sys/ipc.h>#include <semaphore.h>#include <fcntl.h>#define FIFO "myfifo"#define N 5int lock_var;time_t end_time;char buf_r[100];sem_t mutex,full,avail;int fd;void pthread1(void *arg);void pthread2(void *arg);int main(int argc, char *argv[]){pthread_t id1,id2;pthread_t mon_th_id;int ret;end_time = time(NULL)+30;/*创建有名管道*/if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST)) printf("cannot create fifoserver\n");printf("Preparing for reading bytes...\n");memset(buf_r,0,sizeof(buf_r));/*打开管道*/fd=open(FIFO,O_RDWR|O_NONBLOCK,0);if(fd==-1){perror("open");exit(1);}/*初始化互斥信号量为1*/ret=sem_init(&mutex,0,1);/*初始化avail信号量为N*/ret=sem_init(&avail,0,N);/*初始化full信号量为0*/ret=sem_init(&full,0,0);if(ret!=0){perror("sem_init");}/*创建两个线程*/ret=pthread_create(&id1,NULL,(void *)productor, NULL); if(ret!=0)perror("pthread cread1");ret=pthread_create(&id2,NULL,(void *)consumer, NULL); if(ret!=0)perror("pthread cread2");pthread_join(id1,NULL);pthread_join(id2,NULL);exit(0);}/*生产者线程*/void productor(void *arg){int i,nwrite;while(time(NULL) < end_time){/*P操作信号量avail和mutex*/sem_wait(&avail);sem_wait(&mutex);/*生产者写入数据*/if((nwrite=write(fd,"hello",5))==-1){if(errno==EAGAIN)printf("The FIFO has not been read yet.Please try later\n"); }elseprintf("write hello to the FIFO\n");/*V操作信号量full和mutex*/sem_post(&full);sem_post(&mutex);sleep(1);}}/*消费者线程*/void consumer(void *arg){int nolock=0;int ret,nread;while(time(NULL) < end_time){/*P操作信号量full和mutex*/sem_wait(&full);sem_wait(&mutex);memset(buf_r,0,sizeof(buf_r));if((nread=read(fd,buf_r,100))==-1){if(errno==EAGAIN)printf("no data yet\n");}printf("read %s from FIFO\n",buf_r);/*V操作信号量avail和mutex*/sem_post(&avail);sem_post(&mutex);sleep(1);}}(2)条件变量的考虑#include <stdio.h>#include <pthread.h>#define BUFFER_SIZE 4#define OVER (-1)struct producers//定义生产者条件变量结构{int buffer[BUFFER_SIZE];pthread_mutex_t lock;int readpos, writepos;pthread_cond_t notempty;pthread_cond_t notfull;};//初始化缓冲区void init(struct producers *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 producers *b, int data){pthread_mutex_lock(&b->lock);//当缓冲区为满时等待while((b->writepos+1)%BUFFER_SIZE==b->readpos) {pthread_cond_wait(&b->notfull,&b->lock);}b->buffer[b->writepos]=data;b->writepos++;if(b->writepos>=BUFFER_SIZE) b->writepos=0;//发送当前缓冲区中有数据的信号pthread_cond_signal(&b->notempty);pthread_mutex_unlock(&b->lock);}int get(struct producers *b){int data;pthread_mutex_lock(&b->lock);while(b->writepos==b->readpos){pthread_cond_wait(&b->notempty,&b->lock); }data=b->buffer[b->readpos];b->readpos++;if(b->readpos>=BUFFER_SIZE) b->readpos=0; pthread_cond_signal(&b->notfull);pthread_mutex_unlock(&b->lock);return data;}struct producers buffer;void *producer(void *data){int n;for(n=0;n<10;n++){printf("Producer : %d-->\n",n);put(&buffer,n);}put(&buffer,OVER);return NULL;}void *consumer(void *data){int d;while(1){d=get(&buffer);if(d==OVER) break;printf("Consumer: --> %d\n",d);}return NULL;}int main(){pthread_t tha,thb;void *retval;init(&buffer);pthread_create(&tha,NULL,producer,0); pthread_create(&thb,NULL,consumer,0); pthread_join(tha,&retval);pthread_join(thb,&retval);return 0;}。

生产者与消费者实验报告(精品)

生产者与消费者实验报告(精品)

一、实验目的利用Windows提供的API函数,编写程序,解决生产者与消费者问题,实现进程的互斥与同步。

二、实验内容本实验要求设计在同一个进程地址空间内执行的两个线程。

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

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

生产者线程生产物品时,若无空缓冲区可用,生产者线程必须等待消费者线程释放出一个空缓冲区;消费者线程消费物品时,若缓冲区为空,消费者线程将被阻塞,直到新的物品被生产出来。

生产者和消费者使用N个不同的缓冲区(N 为一个确定的数值,例如N=32)。

需要使用如下信号量:一个互斥信号量,用以阻止生产者线程和消费者线程同时操作缓冲区列表;一个信号量,当生产者线程生产出一个物品时可以用它向消费者线程发出信号;一个信号量,消费者线程释放出一个空缓冲区时可以用它向生产者线程发出信号;三、实验步骤1.创建信号量根据题目的要求,首先创建信号量。

本次实验共需使用三个信号量:一个用以阻止生产者线程和消费者线程同时操作缓冲区列表的互斥信号量,一个当生产者线程生产出一个物品时可以用它向消费者线程发出信号的信号量以及一个消费者线程释放出一个空缓冲区时可以用它向生产者线程发出信号的信号量。

使用Windows提供的CreateSemaphore函数和CreateMutex创建一个新的信号量。

CreateSemaphore函数原型:HANDLE CreateSemaphore{LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,LONG lInitialCount,LONG lMaximumCount,LPCTSTR lpName};如执行成功,返回信号量对象的句柄;零表示出错。

本程序所使用的该函数中各参数的解释:1.lpSemaphoreAttributesSECURITY_ATTRIBUTES,指定一个SECURITY_ATTRIBUTES结构,或传递零值,表示采用不允许继承的默认描述符。

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

生产者和消费者问题实验报告
HANDLE hMutex ); i. EnterCriticalSection 的用法: 功能:用于等待之的呢过临界区对象的所有权。 格式: VOID EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection ); j.LeaveCriticalSection 的用法 功能:释放指定临界区对象的所有权。 格式: VOID LeaveCriticalSection( LPCRITICAL_SECTION lpCriticalSection ); 2)程序结构
#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;
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 FindProducePositon();
int FindBufferPosition(int);
int main(void)
{
DWORD wait_for_all;
ifstream inFile;
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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

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

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

•提示本实验的主要目的是模拟操作系统中进程同步和互斥。

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

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

(1)间接制约。

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

(2)直接制约。

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

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

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

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

一般来说,进程间的通信根据通信内容可以划分为两种:即控制信息的传送与大批量数据传送。

有时,也把进程间控制在本实验中,进程之间要进行通信来操作同一缓冲区。

一般来说,进程间的通信根据通信内容可以划分为两种:即控制信息的传送与大批量数据传送。

有时,也把进程间控制信息的交换称为低级通信,而把进程间大批量数据的交换称为高级通信。

目前,计算机系统中用得比较普遍的高级通信机制可分为3大类:共享存储器系统、消息传递系统及管道通信系统。

•共享存储器系统共享存储器系统为了传送大量数据,在存储器中划出一块共享存储区,诸进程可通过对共享存储区进行读数据或写数据以实现通信。

进程在通信之前,向系统申请共享存储区中的一个分区,并为它指定一个分区关键字。

信息的交换称为低级通信,而把进程间大批量数据的交换称为高级通信。

目前,计算机系统中用得比较普遍的高级通信机制可分为3大类:共享存储器系统、消息传递系统及管道通信系统。

•消息传递系统在消息传递系统中,进程间的数据交换以消息为单位,在计算机网络中被称为报文。

消息传递系统的实现方式又可以分为以下两种:(1)直接通信方式发送进程可将消息直接发送给接收进程,即将消息挂在接收进程的消息缓冲队列上,而接收进程可从自己的消息缓冲队列中取得消息。

(2)间接通信方式发送进程将消息发送到指定的信箱中,而接收进程从信箱中取得消息。

这种通信方式又称信箱通信方式,被广泛地应用于计算机网络中。

相应地,该消息传递系统被称为电子邮件系统。

•管道通信系统向管道提供输入的发送进程,以字符流方式将大量的数据送入管道,而接收进程从管道中接收数据。

由于发送进程和接收进程是利用管道进行通信的,故称为管道通信。

为了协调发送和接收双方的通信,管道通信机制必须提供以下3方面的协调功能。

(1)互斥当一个进程正在对pipe文件进行读或写操作时,另一个进程必须等待。

(2)同步当写进程把一定数量的数据写入pipe文件后,便阻塞等待,直到读进程取走数据后,再把写进程唤醒。

(3)确认对方是否存在只有确定对方已存在时,才能进行管道通信,否则会造成因对方不存在而无限制地等待。

在这个问题当中,我们采用信号量机制进行进程之间的通信,设置两个信号量,空的信号量和满的信号量。

在Linux系统中,一个或多个信号量构成一个信号量集合。

使用信号量机制可以实现进程之间的同步和互斥,允许并发进程一次对一组信号量进行相同或不同的操作。

每个P、V操作不限于减1或加1,而是可以加减任何整数。

在进程终止时,系统可根据需要自动消除所有被进程操作过的信号量的影响1.缓冲区采用循环队列表示,利用头、尾指针来存放、读取数据,以及判断队列是否为空。

缓冲区中数组大小为10;2.利用随机函数rand()得到A~Z的一个随机字符,作为生产者每次生产的数据,存放到缓冲区中;3. 使用shmget()系统调用实现共享主存段的创建,shmget()返回共享内存区的ID。

对于已经申请到的共享段,进程需把它附加到自己的虚拟空间中才能对其进行读写。

4.信号量的建立采用semget()函数,同时建立信号量的数量。

在信号量建立后,调用semctl()对信号量进行初始化,例如本实习中,可以建立两个信号量SEM_EMPTY、SEM_FULL,初始化时设置SEM_EMPTY为10,SEM_FULL为0。

使用操作信号的函数semop()做排除式操作,使用这个函数防止对共享内存的同时操作。

对共享内存操作完毕后采用shmctl()函数撤销共享内存段。

5.使用循环,创建2个生产者以及2个消费者,采用函数fork()创建一个新的进程。

6.一个进程的一次操作完成后,采用函数fflush()刷新缓冲区。

7.程序最后使用semctl()函数释放内存。

模拟程序的程序流程图如下所示:1.主程序流程图:2.生产者进程流程图3.消费者进程流程图4.P操作流程图5.V操作流程图四、实现代码为:// exet5.cpp//#include "stdafx.h"#include <stdio.h>#include <stdlib.h>#define mSIZE 3#define pSIZE 20staticintmemery[mSIZE] = {0};staticint process[pSIZE] = {0};//static int process[pSIZE] = {2,3,2,1,5,2,4,5,3,2,5,2}; //static int process[pSIZE] = {7,10,1,2,10,3,10,4,2,3,10,3,2,1,2,10,1,7,10,1};void build();void LRU();int main(intargc, char *argv[]){printf("Random sequence is as follows:\n");build();printf("\nInvoking LRU Algorithn: \n");LRU();return 0;}void build(){inti = 0;for(i=0; i<pSIZE; i++){process[i] = (int)(10.0*rand()/(RAND_MAX));printf("%d ",process[i]);}printf("\n");}void LRU(){int flag[mSIZE] = {0};inti = 0, j = 0;int m = -1, n = -1;int max = -1,maxflag = 0;int count = 0;for(i = 0; i<pSIZE; i++){//Find the first free Physical Block for(j=0; j<mSIZE; j++){if(memery[j] == 0){m = j;break;}}//Find if there are same processes for(j = 0; j <mSIZE; j++){if(memery[j] == process[i]){n = j;}}//Find free PBfor(j = 0; j <mSIZE;j++){if(flag[j]>maxflag){maxflag = flag[j];max = j;}}if(n == -1) // Find no same process {if(m != -1) // find free PB{memery[m] = process[i];flag[m] = 0;for(j = 0;j <= m; j++){flag[j]++;}m = -1;}else //NO find free PB{memery[max] = process[i];flag[max] = 0;for(j = 0;j <mSIZE; j++){flag[j]++;}max = -1;maxflag = 0;count++;}}else // Find same process {memery[n] = process[i]; flag[n] = 0;if(m != -1) //find free PB {flag[m] = 0;}for(j = 0;j <mSIZE; j++){flag[j]++;}max = -1;maxflag = 0;n = -1;}for(j = 0 ;j <mSIZE; j++){printf("%d ",memery[j]);}printf("\n");}printf("\nThe times of page conversion is: %d\n",count);}五、在虚拟机上的具体操作及结果执行exe5.c文件选择Applications→Acecessories→Terminal,执行文件:依次预处理→编译→汇编→连接→执行用文件,编译通过之后-o执行。

报错!!!!错误显示为很多头文件没有预定义。

连续查找之后得知原因是链接不上pthread 库在执行命令后面加上-pthread,即新命令格式为:gcc -oexe5exe5.c–lpthread,重新执行后的结果显示如下截图:其中1表示缓冲区被生产者producer1或者二producer2写入了Item,0表示没有写入数据或者被消费者consumer1或者consumer2消耗掉六、实验总结及思考1、本次实验是关于生产者与消费者之间互斥和同步的问题。

相关文档
最新文档