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

合集下载

生产者消费者实验报告

生产者消费者实验报告

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

“生产者消费者”实验

“生产者消费者”实验

“生产者消费者”实验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。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

河北建筑工程学院实验报告年月日班级物联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;}实验结果。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

(2)初始化信号量。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

饥饿则是指某个线程无法获得所需的资源,一直处于等待状态。

为了避免这些问题的发生,我们需要合理设计线程的调度策略和资源分配策略。

五、实验总结
通过本次实验,我们深入理解了生产者消费者问题的本质和解决方案。

我们学会了使用互斥锁和条件变量来实现线程之间的同步和通信,并通过实验观察到了生产者和消费者之间的交互过程。

同时,我们也意识到了在并发编程中可能出现的死锁和饥饿问题,需要采取相应的策略进行预防和解决。

在今后的学习和工作中,我们将继续深入研究并发编程的相关知识,掌握更多解决并发问题的技巧和方法。

并发编程是计算机科学中的重要领域,对于提高程序的性能和效率具有重要意义。

通过不断学习和实践,我们相信能够在并发编程领域取得更大的成果。

相关文档
最新文档