生产者与消费者实验报告

合集下载

实验三 生产者-消费者问题

实验三 生产者-消费者问题

实验三生产者-消费者问题的实现实验类型验证性实验实验目的通过生产者-消费者问题的模拟,加深对进程同步、共享存储器通信的理解。

实验要求实现生产者消费者问题模拟,显示每次添加和读取数据时缓冲区的状态,生产者和消费者用进程模拟,缓冲区用共享内存来实现。

一个大小为3的缓冲区,初始为空;2个生产者:随机等待一段时间,往缓冲区添加数据,若缓冲区已满,等待消费者取走数据后再添加,重复6次。

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

实验指导一、共享存储区通信1、共享存储区机制的概念共享存储区(Share Memory)是UNIX系统中通信速度最高的一种通信机制。

该机制可使若干进程共享主存中的某一个区域,且使该区域出现(映射)在多个进程的虚地址空间中。

另一方面,一个进程的虚地址空间中又可连接多个共享存储区,每个共享存储区都有自己的名字。

当进程间欲利用共享存储区进行通信时,必须先在主存中建立一共享存储区,然后将它附接到自己的虚地址空间上。

此后,进程对该区的访问操作,与对其虚地址空间的其它部分的操作完全相同。

进程之间便可通过对共享存储区中数据的读、写来进行直接通信。

应当指出,共享存储区机制只为进程提供了用于实现通信的共享存储区和对共享存储区进行操作的手段,然而并未提供对该区进行互斥访问及进程同步的措施。

因而当用户需要使用该机制时,必须自己设置同步和互斥措施才能保证实现正确的通信。

2、涉及的系统调用(1)shmget( )创建、获得一个共享存储区。

系统调用格式:shmid=shmget(key,size,flag)该函数使用头文件如下:#include<sys/types.h>#include<sys/ipc.h>#include<sys/shm.h>参数定义int shmget(key,size,flag);key_t key;int size,flag;其中:key是共享存储区的名字;(唯一标识共享内存的键值。

生产者消费者实验报告

生产者消费者实验报告

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

河北建筑工程学院实验报告年月日班级物联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);}}}}}五、实验结果运行程序,显示如下:。

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

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

生产者与消费者问题实验报告生产者与消费者问题实验报告篇一:生产者和消费者问题实验报告实验报告课程名称:操作系统实验名称:生产者和消费者问题学号:学生姓名:班级:指导教师:评分:实验日期: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)互斥:通过公用信号量实现生产者和消费者对环形缓冲区的互斥访问,防止了同时操作缓冲区的问题。

生产者消费者实验报告

生产者消费者实验报告

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

实验内容与步骤:1.进程的互斥与同步。

编写一段程序,模拟生产者和消费者线程,实现进程的互斥与同步。

2.利用VC++6.0实现上述程序设计和调试操作,对于生产者和消费者线程操作的成功与否提供一定的提示框。

3.通过阅读和分析实验程序,熟悉进程的互斥与同步的概念。

程序设计思路:关于这个生产者与消费者进程,我主要设计了两个线程,一个生产者线程,一个消费者线程。

整个进程随着这两个线程的创建,运行,终止而进行。

在程序的开始,首先我创建了一个结构struct,它包括的基本数据有:生产物品缓冲区(用队列来表示),一个标志缓冲区空间多少的信号量m_S_Empty,一个标志缓冲区已有物品多少的信号量m_S_Full,一个互斥信号量m_M_Mutex 防止生产者与消费者同时访问缓冲区间,一个判断生产者是否要结束生产的bool类型标志producerfinished,若为true,则两个线程都终止。

进入主程序以后,首先对这些struct中的基本数据进行一个个赋值,然后创建生产者与消费者两个线程,等待两个线程都结束时,关闭进程。

要知道在main主函数中两个线程的创建语句就是对两个线程各自进入函数的运行,生产者函数中通过一个for循环,可以控制生产者进行多次生产,不是生产一次就结束了。

消费者函数中通过一个while循环,当生产者没有结束生产时可以控制消费者进行多次消费,不是消费一次就不会再来消费了,除非生产者已结束生产,即producerfinished的值变为true。

实验主要程序及注释:#include"stdafx.h"#include<windows.h>#include<iostream>#include<queue>#include<process.h>using namespace std;DWORD WINAPI Consumer(void*);//声明消费者函数DWORD WINAPI Producer(void*);//声明生产者函数#define N 10//定义缓冲区数量/*数据结构的定义*/struct MyData{HANDLE m_S_Empty;// 生产者SemaphoreHANDLE m_S_Full; // 消费者SemaphoreHANDLE m_M_Mutex;//互斥信号量queue<int> food; //定义共享缓冲区bool producerfinished;//标志着生产者是否结束生产};int j=0;//只是为了输出方便观察线程执行次数int main(){ /*对各个信号量赋值*/MyData mydata;//创建一个MyData数据类型的实体mydatamydata.m_M_Mutex = CreateMutex(NULL, false, NULL);//"false"表示刚刚创建的这个信号量不属于®¨²任何线程mydata.m_S_Empty = CreateSemaphore(NULL, N, N, NULL);//初始计数为Nmydata.m_S_Full = CreateSemaphore(NULL, 0, N, NULL);//初始计数为0mydata.producerfinished=false;//生产者结束标志刚开始设置为false,表示没有结束/*创建生产者和消费者线程*/HANDLE handles[2];handles[0] = CreateThread(NULL,0,&Producer,(void*)&mydata,0,0);handles[1] = CreateThread(NULL,0,&Consumer,(void*)&mydata,0,0);WaitForMultipleObjects(2, handles, true, INFINITE); //等待两个线程都结束才往下执行 CloseHandle(mydata.m_M_Mutex);CloseHandle(mydata.m_S_Full);CloseHandle(mydata.m_S_Empty);}/*生产者函数*/DWORD WINAPI Producer(void* lp){MyData * md = (MyData*)lp;for(int i =0 ; i < 100; i++){WaitForSingleObject(md->m_S_Empty, INFINITE);//缓冲区有空间才可以往下WaitForSingleObject(md->m_M_Mutex, INFINITE);//消费者没有在操作缓冲区生产者才可以执行/*将所生产的物品放到指定的缓冲区中*/md->food.push(1);printf("%d\t生产1个物品,共有%d个物品\t\t%d\n",j++,md->food.size(),GetCurrentThreadId());//输出缓冲区信息以及线程信息ReleaseMutex(md->m_M_Mutex);//释放互斥信号量ReleaseSemaphore(md->m_S_Full, 1, NULL);//有物品的缓冲区增加一个}md->producerfinished=true;//若出了for循环,生产者结束生产,控制消费者线程结束return 0;}/*消费者函数*/DWORD WINAPI Consumer(void* lp){MyData * md = (MyData*)lp;while(!md->producerfinished){//若生产者没有结束生产,可以继续往下执行WaitForSingleObject(md->m_S_Full,INFINITE);//若缓冲区没有空,则可以往下执行WaitForSingleObject(md->m_M_Mutex,INFINITE);//若生产者没有在操作缓冲区,则消费则可以操作/*消费一个物品*/md->food.pop();printf("%d\t消费1个物品,共有%d个物品\t\t%d\n",j++,md->food.size(),GetCurrentThreadId());//输出缓冲区信息以及线程信息ReleaseMutex(md->m_M_Mutex); //释放互斥信号量ReleaseSemaphore(md->m_S_Empty,1,NULL);//空缓冲区增加一个}return 0;}实验中遇到的问题及解决:我的这个程序是结合了老师ppt上给的程序框架,然后理解了精品课程上给的程序自己重新整理写的。

生产者与消费者实验报告

生产者与消费者实验报告

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

生产者和消费者实验报告【实验目的】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;}//生产一个产品。

简单模拟了一下,仅输出新产品的ID号void Produce(){std::cerr << "Producing " << ++ProductID << " ... ";std::cerr << "Succeed" << std::endl;}//把新生产的产品放入缓冲区void Append(){std::cerr << "Appending a product ... ";g_buffer[in] = ProductID;in = (in+1)%SIZE_OF_BUFFER;std::cerr << "Succeed" << std::endl;//输出缓冲区当前的状态for (int i=0;i<SIZE_OF_BUFFER;++i){std::cout << i <<": " << g_buffer[i];if (i==in) std::cout << " <-- 生产";if (i==out) std::cout << " <-- 消费";std::cout << std::endl;}}//从缓冲区中取出一个产品void Take(){std::cerr << "Taking a product ... ";ConsumeID = g_buffer[out];out = (out+1)%SIZE_OF_BUFFER;std::cerr << "Succeed" << std::endl;//输出缓冲区当前的状态for (int i=0;i<SIZE_OF_BUFFER;++i){std::cout << i <<": " << g_buffer[i];if (i==in) std::cout << " <-- 生产";if (i==out) std::cout << " <-- 消费";std::cout << std::endl;}}//消耗一个产品void Consume(){std::cerr << "Consuming " << ConsumeID << " ... ";std::cerr << "Succeed" << std::endl;}//生产者DWORD WINAPI Producer(LPVOID lpPara){while(g_continue){WaitForSingleObject(g_hFullSemaphore,INFINITE);WaitForSingleObject(g_hMutex,INFINITE);Produce();Append();Sleep(1500);ReleaseMutex(g_hMutex);ReleaseSemaphore(g_hEmptySemaphore,1,NULL);}return 0;}//消费者DWORD WINAPI Consumer(LPVOID lpPara){while(g_continue){WaitForSingleObject(g_hEmptySemaphore,INFINITE);WaitForSingleObject(g_hMutex,INFINITE);Take();Consume();Sleep(1500);ReleaseMutex(g_hMutex);ReleaseSemaphore(g_hFullSemaphore,1,NULL);}return 0;}【实验结果】具体程序见附件(网络查找)【实验反思】本次实验是关于生产者和消费者之间互斥和同步的问题。

问题的实质是P,V 操作,实验设一个共享缓冲区,生产者和消费者互斥的使用,当一个线程使用缓冲区的时候,另一个让其等待知道前一个线程释放缓冲区为止。

通过本次实验,我们对操作系统的P,V进一步的认识,深入的了解P,V操作的实质和其重要性。

课本的理论知识进一步阐述了现实的实际问题。

相关文档
最新文档