实验生产者消费者问题

合集下载

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

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

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

文档下载后可定制修改,请根据实际需要进行调整和使用,谢谢!本店铺为大家提供各种类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,想了解不同资料格式和写法,敬请关注!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来代表缓冲区。

“生产者消费者”实验

“生产者消费者”实验

“生产者消费者”实验1.实验目的“生产者消费者”问题是一个著名的同时性编程问题的集合。

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

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

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

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

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

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

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

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

(2)画出流程图本实验流程图如下图9.5 所示。

《嵌入式Linux应用程序开发详解》——第9章、多线程编程图9.5 “生产者消费者”实验流程图(3)编写代码本实验代码如下:/*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);}《嵌入式Linux应用程序开发详解》——第9章、多线程编程/*初始化互斥信号量为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);}/*生产者线程*/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);}}4.实验结果运行该程序,得到如下结果:[root@(none) tmp]#./execPreparing for reading bytes...write hello to the FIFOread hello from FIFOwrite hello to the FIFOread hello from FIFOwrite hello to the FIFO《嵌入式Linux应用程序开发详解》——第9章、多线程编程read hello from FIFOwrite hello to the FIFOread hello from FIFO。

生产者消费者问题模拟实现(z)

生产者消费者问题模拟实现(z)

int *pcq; //信号量队列指针
} Seamphore;
int producerCongestionQueue[processNum]; //等待信号量 empty
的阻塞队列 int consumerCongestionQueue[processNum]; //等待信
号量 full 的阻塞队列
用信号量机制解决生产者—消费者问题可描述如下:
item B[k];
semaphore empty; empty=k; //可以使用的空缓冲区数
semaphore full; full=0;
//缓冲区内可以使用的产品数
semaphore mutex; mutex=1; //互斥信号量
int in=0; //放入缓冲区指针
号量 s 的阻塞队列中。
(2)V(s):s.value++;若 s.value≤0,则执行 V(s)的进程从等待
信号量 s 的阻塞队列中唤醒头一个进程,然后自己继续执行。若
s.value>0 ,则执行 V(s)
的进程继续执行;
1.2.3 信号量实现互斥
信号量和 PV 操作可用来解决进程互斥问题。为使多个进程能互斥地
append to B[in];
out =
(out+1)%k;
in = (in+1)%k;
V(mutex);
V(mutex);
V(empty);
V(full);
consume();
}
}}
}
Coend
程序中的 P(mutex)和 V(mutex)必须成对出现,夹在两者之间的代码
段是临界区;施加于信号量 empty 和 full 上的 PV 操作也必须成对出

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

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

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

进程管理----生产者和消费者问题(实验报告)

进程管理----生产者和消费者问题(实验报告)

计算机与信息工程系实验报告班级计算机1001班姓名李双贺时间2011年10月19日地点文理楼A504实验名称进程管理----生产者和消费者问题实验目的:(1)加深对进程概念的理解,明确进程和程序的区别。

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

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

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

实验内容问题描述:考虑有一些生产者和消费者进程,生产者进程生产信息并把它们放入缓冲池中,消费者从缓冲池中取走信息。

生产者—消费者问题是相互合作的进程关系的一种抽象,如在输入时,输入进程是生产者,计算进程是消费者;而在输出时,则计算进程是生产者,打印进程是消费者。

请使用信号量机制来解决生产者—消费者问题。

互斥关系:(I)设缓冲池有n个单元。

(II)当n个单元装满时,生产者必须等待。

(III)当缓冲池空时,消费者必须等待。

参考算法://创建生产者线程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;}//生产者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;}实验结果。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

C语言编程模拟生产者和消费者问题(附代码程序)

C语言编程模拟生产者和消费者问题(附代码程序)

C语言编程模拟生产者和消费者问题(附代码程序)实验三编程模拟生产者和消费者问题一、实验目的和要求模拟实现用同步机构避免发生进程执行时可能出现的与时间有关的错误。

进程是程序在一个数据集合上运行的过程,进程是并发执行的,也即系统中的多个进程轮流地占用处理器运行。

我们把若干个进程都能进行访问和修改的那些变量称为公共变量。

由于进程是并发地执行的,所以,如果对进程访问公共变量不加限制,那么就会产生“与时间有关”的错误,即进程执行后所得到的结果与访问公共变量的时间有关。

为了防止这类错误,系统必须要用同步机构来控制进程对公共变量的访问。

一般说,同步机构是由若干条原语一一同步原语一一所组成。

本实习要求学生模拟PV操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。

二、实验环境Windows操作系统和VisualC++6.0专业版或企业版三、实验步骤模拟PV操作同步机构,且用PV操作解决生产者一一消费者问题。

[提示]:⑴PV操作同步机构,由P操作原语和V操作原语组成,它们的定义如下:P操作原语P(s):将信号量s减去1,若结果小于0,则执行原语的进程被置成等待信号量s的状态。

V操作原语V(s):将信号量s加1,若结果不大于0,则释放一个等待信号量s的进程。

这两条原语是如下的两个过程:procedurep(vars:semaphore);begi ns:=s-1;ifs<0the nW(s)en d{p}procedurev(vars:semaphore);egin s:=s+1;ifs _Othe nR(s)en d{v}其中W (s)表示将调用过程的进程置为等待信号量s的状态;R (s)表示释放一个等待信号量s的进程。

在系统初始化时应把semaphore定义为某个类型,为简单起见,在模拟实习中可把上述的semaphore直接改成integer。

(2) 生产者一一消费者问题。

假定有一个生产者和一个消费者,生产者每次生产一件产品,并把生产的产品存入共享缓冲器以供消费者取走使用。

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

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

实验二生产者-消费者问题实验目的掌握进程同步和互斥算法,掌握WIN32 API中基本的同步对象,使用WIN32 API解决实际问题。

实验内容生产者-消费者问题是一个经典的进程同步问题,该问题最早由Dijkstra提出,用以演示他提出的信号量机制。

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

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

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

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

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

本实验要求设计并实现一个进程,该进程拥有一个生产者线程和一个消费者线程,它们使用N个不同的缓冲区(N为一个确定的数值,本实验中取N=16)。

你需要使用如下信号量:●一个互斥信号量,用以阻止生产者线程和消费者线程同时操作缓冲区列表;●一个信号量,当生产者线程生产出一个物品时可以用它向消费者线程发出信号;●一个信号量,消费者线程释放出一个空缓冲区时可以用它向生产者线程发出信号;下面给出的是解决这一问题的伪代码,你可以在此基础上编写自己的程序:#define N 16//定义信号量semaphore mutex = 1;semaphore full = 0;semaphore empty = N;//定义共享缓冲区buf_type buffer[N];main(…){…//创建生产者和消费者线程CreateThread(…, Producer, …);CreateThread(…, Consumer, …);…}Producer(){buf_type *nextp;while(TRUE){sleep(rand); //休眠一段随机时间produce_item(nextp); //生产一个物品P(empty); //请求一个空缓冲区//操作缓冲区池P(mutex);add nextp to buffer; //将物品放置在一个空缓冲区中printf(“produce a new item to the %d-th slot”, ….);V(mutex); //用信号通知一个满的缓冲区V(full);}}Consumer(){buf_type *nextc;while(TRUE){sleep(rand); //休眠一段随机时间P(full); //请求一个满缓冲区//操作缓冲区池P(mutex);remove an item to nextc; //获得物品,然后释放缓冲区printf(“consume an item in the %d-th slot”, ….);V(mutex); //用信号通知一个空的缓冲区V(empty);}}上述伪代码只是为了提供一个解决问题的思路,与Windows的同步原语无关。

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

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

操作系统实验报告——生产者和消费者问题姓名:学号:班级:一、实验内容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;}。

1实验1:生产者消费者问题

1实验1:生产者消费者问题

福建农林大学金山学院实验报告系(教研室):专业:计算机科学与技术年级:实验课程:生产者与消费者实验姓名:学号:实验室号:1#608计算机号:实验时间:指导教师签字: 成绩:实验1:生产者消费者问题一、实验目的生产者消费者问题是操作系统中经典的同步和互斥问题.通过实验,要求学生掌握两者之间的同步信号量和互斥信号量的使用,更深刻了解临界资源、同步和互斥的概念。

二、实验要求1.一组生产者通过一个具有N个缓冲区的缓冲池循环不断地向一组消费者提供产品。

2.建一个队列, 队列的长度由n记录, 定义两个指针,分别指向队列的头和尾消费者从头指针读取数据,每读取一个数据把n——,生产者把数据写入尾指针,每写入一个数据就n++,当n=N的时候生产者暂停写入数据.3.注意:缓冲池队列,用互斥锁保护.三、实验内容和原理1.分别画出生产者和消费者的流程图2.针对生产者和消费者问题,可以分为哪几种情况,使用了哪些原语?分别代表什么意思?过程如何?阐述哪些进程之间存在同步,哪些进程之间存在互斥.3.缓冲区是否为临界资源?是否可以循环使用?通过什么来实现?举例说明(可画图)四、实验环境1. 硬件:PC机;2. 软件:Windows操作系统、VC6。

0。

五、算法描述及实验步骤#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];DWORD 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;}void Produce(){ std::cerr << ”Producing " 〈〈++ProductID 〈〈” 。

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

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

实验报告(学生打印后提交)实验名称: 生产者和消费者问题实验时间: 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, 互斥量出现指打开互斥锁。

实验二 生产者消费者问题

实验二  生产者消费者问题

电子科技大学信息与软件学院实验报告(实验)课程名称计算机操作系统学生姓名康彪学生学号2013220202022电子科技大学教务处制表1、实验名称:生产者/消费者问题的实现2、实验学时:23、实验内容和目的:实验目的:通过本实验掌握进程间的同步和互斥机制的使用。

实验内容:1、有一群生产者进程在生产产品,并将这些产品提供给消费者进程去消费。

为使生产者进程与消费者进程能并发执行,在两者之间设置了一个具有n个缓冲区的缓冲池:生产者进程从文件中读取一个数据,并将它存放到一个缓冲区中;消费者进程从一个缓冲区中取走数据,并输出此数据。

生产者和消费者之间必须保持同步原则:不允许消费者进程到一个空缓冲区去取产品;也不允许生产者进程向一个已装满产品且尚未被取走的缓冲区中投放产品。

2、创建3进程(或者线程)作为生产者,4个进程(或者线程)作为消费者。

创建一个文件作为数据源,文件中事先写入一些内容作为数据。

3、生产者和消费者进程(或者线程)都具有相同的优先级。

4、实验原理:利用进程间共享的信号量、互斥锁等控制线程的同步。

相关函数说明:5、实验器材(设备、元器件)(1)学生每人一台PC,安装WindowsXP/2000操作系统。

(2)局域网络环境。

(3)个人PC安装VMware虚拟机和Ubuntu系统。

6、实验步骤:1. 算法思想生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。

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

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

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

2. 流程图3. 程序代码#include <windows.h>#include <iostream.h>#include <fstream.h>#include <string.h>#include <conio.h>//声明所需变量int in=0;int out=0;HANDLE h_Thread[20]; //线程数组HANDLE empty_Semaphore; //表示空缓冲区的信号量HANDLE full_Semaphore; //表示空缓冲区的信号量HANDLE mutex;struct data{int ID;//序号char type;//类型,是生产者还是消费者,p or cdouble delay;//线程延迟的时间,对应生产者生产产品的时间或消费者消费产品的时间};data ThreadInfo[20]; //线程信息数组int length; //线程信息数组中实际的线程个数void Produce(void *p);//生产者进程void Consume(void *p);//消费者进程void input(void);int main(void){input();//初始化临界区对象//InitializeCriticalSection(&PC_Critical);empty_Semaphore=CreateSemaphore(NULL,10,10,NULL);full_Semaphore=CreateSemaphore(NULL,0,10,NULL);mutex = ::CreateMutex(NULL,FALSE,NULL);cout<<"下面生产者和消费者开始工作!!"<<endl;cout<<endl;//创建生产者和消费者线程for(int i=0;i{if(ThreadInfo[i].type=='p')h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Produce),&(ThreadI nfo[i]),0,NULL);elseif(ThreadInfo[i].type=='c')h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Consume),&(Threa dInfo[i]),0,NULL);}//主程序等待各个线程的动作结束WaitForMultipleObjects(length,h_Thread,TRUE,-1);cout<<endl;::Sleep(100);cout<<"所有的生产者和消费者都完成了它们的工作!!"<<endl<<endl;return 0;}//******************************************************************* **********************//生产者进程//******************************************************************* ***********************void Produce(void *p){//局部变量声明int my_id;double my_delay;//从线程信息数组中获得信息my_id =((data*)(p))->ID;my_delay=((data*)(p))->delay;//开始请求生产WaitForSingleObject(empty_Semaphore,-1);::WaitForSingleObject(mutex,-1);//EnterCriticalSection(&PC_Critical);cout<<"生产者"<<my_id<<"发出生产请求。

实验5 模拟生产者-消费者实验

实验5 模拟生产者-消费者实验

实验5 模拟生产者-消费者实验
实验目的
(1)掌握信号量及互斥信号量的使用方法;
(2)掌握共享存储区的使用方法。

实验原理
生产者-消费者(producer-consumer)问题是一个著名的进程同步问题。

它描述的是:有一群生产者进程在生产产品,并将这些产品提供给消费者进程去消费。

为使生产者进程与消费者进程能并发执行,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者进程将它所生产的产品放入一个缓冲区中;消费者进程可从一个缓冲区中取走产品去消费。

尽管所有的生产者进程和消费者进程都是以异步方式运行的,但它们之间必须保持同步,即不允许消费者进程到一个空缓冲区去取产品;也不允许生产者进程向一个已装满产品且尚未被取走的缓冲区中投放产品。

为了保证数据的一致性,必须将信号量机制引入到生产者-消费者问题之中。

对于n个缓冲区,设置互斥信号量mutex使诸进程实现对缓冲池的互斥使用;利用资源信号量empty和full分别表示缓冲池中空缓冲区和满缓冲区的数量。

又假设生产者和消费者进程相互等效,只要缓冲池未满,生产者便可将消息送入缓冲池;只要缓冲池未空,消费者便可从缓冲池中取走一个消息。

6.4 实验内容
模拟生产者-消费者工作机制,由串口接收任务不断接收用户从超级终端输入的数据,模拟成数据的生产者,并将数据存放到共享缓冲区中;由LCD任务不断从共享缓冲区中读取数据,并显示出来,模拟成消费者。

生产者消费者实验报告

生产者消费者实验报告

河北建筑工程学院实验报告2013年11 月26 日班级物联网111姓名李望来学号37 评分实验台号同组人员实验名称进程同步课程名称操作系统仪器名称型号规格仪器编号Java Jdk1.6Eclipse eclipse-SDK-4.2.2一实验目的1.深刻理解进程同步的概念。

2.掌握经典同步问题,生产者——消费者问题。

二实验设备PC机三实验内容在java开发环境下模拟经典进程同步问题,生产者——消费者问题。

1. 设计方案:1、用Java编写程序,运行环境为Eclipse。

2、抽象化生产者与消费者之间的关系,即用进程来产生数据或者使用数据,定义的类有:(1)public class PCTable2(2)class Producer(3)class Consumer3、然后通过接口ActionListener来实现多个生产者与多个消费者之间的关系:(1)、class Producer implements ActionListener(2)、class Consumer implements ActionListener4、还需要有一个缓冲区来存放数据,即通过缓冲区把生产者和消费者联系起来。

2. 流程图:四 程序的主要代码package ch2;import java.awt.*;import java.awt.event.*; import javax.swing.*;public class PCTable2 {static JButton[] jbtn={new JButton("生产者1"),new JButton("生产者2"),new JButton("生产者3"),new JButton("生产者4"),new JButton("消费者1"),new JButton("消费者2"),new JButton("消费者3"),new JButton("消费者4")};static JPanel jpan1 = new JPanel(); static JPanel jpan2 = new JPanel(); static JPanel jpan3 = new JPanel();;创建“生产者”进程缓冲区是否阻塞“生产者”等待“消费者”取出缓冲区的数据创建“消费者”进程“消费者”阻塞缓冲区是否为空输入数据“生产者”生产产品后被唤醒NONOYESstatic JTextField jtf1 = new JTextField();static JTextField jtf2 = new JTextField();static JTextField jtf3 = new JTextField();static JTextField jtf4 = new JTextField();static JTextField jtf5 = new JTextField();static JTextField jtf6 = new JTextField();static JTextField jtf7 = new JTextField();public static void main(String[] args) {JFrame jfrm = new JFrame("生产者-消费者问题");jfrm.setBounds(300, 100,900,400);jfrm.setLayout(null);jpan1.setLayout(null);jpan2.setLayout(null);jpan3.setLayout(null);jtf1.setBounds(100,10,100,30);jtf2.setBounds(300,10,100,30);jtf3.setBounds(50,10,100,30);jtf4.setBounds(250,10,100,30);jtf5.setBounds(100,10,100,30);jtf6.setBounds(200,10,100,30);jtf7.setBounds(300,10,100,30);jpan1.setBounds(0,60,450,50);jpan2.setBounds(450,60,450,50);jpan3.setBounds(200,260,500,50);JLabel jlab1= new JLabel("消费者队列",JLabel.CENTER); jlab1.setBounds(600,30,100,30);jlab1.setOpaque(true);jlab1.setBackground(Color.yellow);JLabel jlab2= new JLabel("生产者队列",JLabel.CENTER); jlab2.setBounds(200,30,100,30);jlab2.setOpaque(true);jlab2.setBackground(Color.yellow);JLabel jlab3 = new JLabel("缓冲区",JLabel.CENTER);jlab3.setBounds(400,220,100,30);jlab3.setOpaque(true);jlab3.setBackground(Color.yellow);jbtn[0].setBounds(100,120,100,30);jbtn[1].setBounds(300,120,100,30);jbtn[2].setBounds(500,120,100,30);jbtn[3].setBounds(700,120,100,30);jbtn[4].setBounds(100,180,100,30);jbtn[5].setBounds(300,180,100,30);jbtn[6].setBounds(500,180,100,30);jbtn[7].setBounds(700,180,100,30);jbtn[0].addActionListener(new Producter());jbtn[1].addActionListener(new Producter());jbtn[2].addActionListener(new Producter());jbtn[3].addActionListener(new Producter());jbtn[4].addActionListener(new Consumer());jbtn[5].addActionListener(new Consumer());jbtn[6].addActionListener(new Consumer());jbtn[7].addActionListener(new Consumer());jpan1.add(jtf1);jpan1.add(jtf2);jpan2.add(jtf3);jpan2.add(jtf4);jpan3.add(jtf5);jpan3.add(jtf6);jpan3.add(jtf7); jfrm.add(jlab1);jfrm.add(jlab2);jfrm.add(jlab3);jfrm.add(jbtn[0]); jfrm.add(jbtn[1]);jfrm.add(jbtn[2]);jfrm.add(jbtn[3]);jfrm.add(jbtn[4]);jfrm.add(jbtn[5]);jfrm.add(jbtn[6]);jfrm.add(jbtn[7]);jfrm.add(jpan1);jfrm.add(jpan2);jfrm.add(jpan3);jtf1.setForeground(Color.BLUE);jtf2.setForeground(Color.BLUE);jtf3.setForeground(Color.BLUE);jtf4.setForeground(Color.BLUE);jtf5.setForeground(Color.BLUE);jtf6.setForeground(Color.BLUE);jtf7.setForeground(Color.BLUE);Font f=new Font("楷体",Font.BOLD,20);jtf1.setFont(f);jtf2.setFont(f);jtf3.setFont(f);jtf4.setFont(f);jtf5.setFont(f);jtf6.setFont(f);jtf7.setFont(f);jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jfrm.setVisible(true);}static class Producter implements ActionListener{JButton bun0=jbtn[0];JButton bun1=jbtn[1];JButton bun2=jbtn[2];JButton bun3=jbtn[3];JButton bun4=jbtn[4];JButton bun5=jbtn[5];JButton bun6=jbtn[6];JButton bun7=jbtn[7];public void actionPerformed(ActionEvent e) {JButton jbtn=(JButton)e.getSource();String str=jbtn.getText();if (jtf3.getText().equals("")){if (jtf5.getText().equals(""))jtf5.setText(str);else{if(jtf5.getText().equals("生产者1")||jtf5.getText().equals("生产者2")|| jtf5.getText().equals("生产者3")||jtf5.getText().equals("生产者4")){if(jtf6.getText().equals(""))jtf6.setText(str);else{if(jtf6.getText().equals("生产者1")||jtf6.getText().equals("生产者2")|| jtf6.getText().equals("生产者3")||jtf6.getText().equals("生产者4")) {if(jtf7.getText().equals(""))jtf7.setText(str);else{if(jtf1.getText().equals("")){jtf1.setText(str);jbtn.setEnabled(false);}elseif(jtf2.getText().equals("")){jtf2.setText(str);bun0.setEnabled(false);bun1.setEnabled(false);bun2.setEnabled(false);bun3.setEnabled(false);}}}}}}}else{jtf3.setText(jtf4.getText());jtf4.setText("");if(jtf4.getText().equals("")){if(jtf3.getText().equals(bun4.getText()))bun4.setEnabled(false);else bun4.setEnabled(true);if(jtf3.getText().equals(bun5.getText()))bun5.setEnabled(false);else bun5.setEnabled(true);if(jtf3.getText().equals(bun6.getText()))bun6.setEnabled(false);else bun6.setEnabled(true);if(jtf3.getText().equals(bun7.getText()))bun7.setEnabled(false);else bun7.setEnabled(true);}else{bun4.setEnabled(false);bun5.setEnabled(false);bun6.setEnabled(false);bun7.setEnabled(false);}}}}static class Consumer implements ActionListener{JButton bun0=jbtn[0];JButton bun1=jbtn[1];JButton bun2=jbtn[2];JButton bun3=jbtn[3];JButton bun4=jbtn[4];JButton bun5=jbtn[5];JButton bun6=jbtn[6];JButton bun7=jbtn[7];public void actionPerformed(ActionEvent e) {JButton jbtn=(JButton)e.getSource();String str=jbtn.getText();if (jtf5.getText().equals("")){if(jtf3.getText().equals("")){jtf3.setText(str);jbtn.setEnabled(false);}else{if(jtf4.getText().equals(""));{jtf4.setText(str);bun4.setEnabled(false);bun4.setEnabled(false);bun5.setEnabled(false);bun6.setEnabled(false);bun7.setEnabled(false);}}}else{jtf5.setText(jtf6.getText());jtf6.setText(jtf7.getText());jtf7.setText(jtf1.getText());jtf1.setText(jtf2.getText());jtf2.setText("");if(jtf1.getText().equals("")){bun0.setEnabled(true);bun1.setEnabled(true);bun2.setEnabled(true);bun3.setEnabled(true);}else{if(jtf2.getText().equals("")){if(jtf1.getText().equals(bun0.getText()))bun0.setEnabled(false);else bun0.setEnabled(true);if(jtf1.getText().equals(bun1.getText()))bun1.setEnabled(false);else bun1.setEnabled(true);if(jtf1.getText().equals(bun2.getText()))bun2.setEnabled(false);else bun2.setEnabled(true);if(jtf1.getText().equals(bun3.getText()))bun3.setEnabled(false);else bun3.setEnabled(true);}else{bun0.setEnabled(false);bun1.setEnabled(false);bun2.setEnabled(false);bun3.setEnabled(false);}}}}}}五实验结果这次生产者与消费者之间的关系的实验我用Java语言编写的,通过接口ActionListener用来将生产者进程与消费者进程实例化。

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

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

格式: 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簪巷

实验一生产者消费者问题

实验一生产者消费者问题

实验一生产者消费者问题一、实验目的1.掌握进程(线程)的同步与互斥。

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

3.掌握多线程编程方法。

二、相关函数VC提供一系列函数用于实现多线程编程以及线程的互斥与同步。

(1)创建线程HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId);该函数在其调用进程的进程空间里创建一个新的线程,并返回已建线程的句柄,其中各参数说明如下:✧lpThreadAttributes:指向一个SECURITY_ATTRIBUTES 结构的指针,该结构决定了线程的安全属性,一般置为NULL;✧dwStackSize:指定了线程的堆栈深度,一般都设置为0;✧lpStartAddress:表示新线程开始执行时代码所在函数的地址,即线程的起始地址。

main()函数是主线程的入口函数,同样,新创建的线程也需要一个入口函数,lpStartAddress 就是指示该函数的地址。

并且这个函数的定义应遵循下面的声明形式DWORD WINAPI ThreadProc(LPVOID lpParameter);✧lpParameter:指定了线程执行时传送给线程的32位参数,即线程函数的参数;✧dwCreationFlags:控制线程创建的附加标志,可以取两种值。

如果该参数为0,线程在被创建后就会立即开始执行;如果该参数为CREATE_SUSPENDED,则系统产生线程后,该线程处于阻塞状态,并不马上执行,直至函数ResumeThread被调用;✧lpThreadId:该参数返回所创建线程的ID;✧函数返回值:如果创建成功则返回线程的句柄,否则返回NULL。

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

福建农林大学金山学院实验报告
系(教研室):专业:计算机科学与技术年级:
实验课程:生产者与消费者实验姓名:学号:
实验室号:1#608
计算机号:实验时间:指导教师签字:成绩:
实验1:生产者消费者问题
一、实验目的
生产者消费者问题是操作系统中经典的同步和互斥问题。

通过实验,要求学生掌握两者之间的同步信号量和互斥信号量的使用,更深刻了解临界资源、同步和互斥的概念。

二、实验要求
1.一组生产者通过一个具有N个缓冲区的缓冲池循环不断地向一组消费者提供产
品。

2.建一个队列, 队列的长度由n记录, 定义两个指针, 分别指向队列的头和尾消费
者从头指针读取数据,每读取一个数据把n--,生产者把数据写入尾指针, 每写
入一个数据就n++,当n=N的时候生产者暂停写入数据。

3.注意:缓冲池队列,用互斥锁保护。

三、实验内容和原理
1.分别画出生产者和消费者的流程图
2.针对生产者和消费者问题,可以分为哪几种情况,使用了哪些原语?分别代表
什么意思?过程如何?阐述哪些进程之间存在同步,哪些进程之间存在互斥。

3.缓冲区是否为临界资源?是否可以循环使用?通过什么来实现?举例说明(可
画图)
四、实验环境
1. 硬件:PC机;
2. 软件:Windows操作系统、VC6.0。

五、算法描述及实验步骤
#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];
DWORD 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,&consum erID[i]);
if (hThreads[i]==NULL) return -1;
}
while(g_continue){
if(getchar()){ //按回车后终止程序运行
g_continue = false;
}
}
return 0;
}
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;
}
六、调试过程
程序有错误:
在94 和108行分别少了两个封号。

经改正后无错误如图所示:
七、实验结果
七、总结
通过这次试验我了解了生产者消费者问题是操作系统中经典的同步和互斥问题。

基本上掌握了两者之间的同步信号量和互斥信号量的使用,更深刻了解临界资源、同步和互斥的概念。

并且在错误的调试中对知识有了更深的掌握。

附录:。

相关文档
最新文档