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

合集下载

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

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

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

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

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

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

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

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

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

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

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

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

《操作系统》实验报告生产者和消费者的问题一、实验目的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.在多线程矩阵开发实验中,刚开始定义矩阵太小,测试结果不太明显,后面通过把矩阵改大,并且线程数目不断变化使得结果明显。

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

操作系统生产者与消费者实验
}
void Consume()
{
ConsumeID = buffer[out];
printf("消费者消费产品%d...\n",ConsumeID);
Sleep(2000);
printf("从缓冲区%d拿走一个产品\n",out);
out = (out+1)%n;
}
DWORD WINAPI Producer(LPVOID lpPara)
HANDLE Full;
HANDLE Empty;
void Produce()
{
buffer[in] = ++ProductID;
printf("生产者生产产品%d中...\n",ProductID);
Sleep(2000);
printf("在缓冲区%d添加一个产品\n",in);
in = (in+1)%n;
f)缓冲池不要求是循环环形缓冲区,也不要求一定是顺序访问,生产者可以将产品投放入任意的空缓冲区。
3、实验仪器设备
PC兼容机。
4、程序流程图
(1)、生产者流程图
(2)、消费者流程图
5、源代码
#include <windows.h>
#include <stdio.h>
const unsigned short n = 10;
{
while(g_continue){
if(WaitForSingleObject(Full,2000)==WAIT_TIMEOUT)
{
printf("consumer full time out!\n");

操作系统原理实验--生产者消费者问题

操作系统原理实验--生产者消费者问题

操作系统课程设计(一号黑体加粗)用多进程同步方法解决生产者-消费者问题(小二黑体加粗)院系:小二黑体加粗班级:学号:姓名:同组者:时间:目录(小二黑体加粗)一、题目:............................... 错误!未定义书签。

二、设计目的:........................... 错误!未定义书签。

三、总体设计思想概述:................... 错误!未定义书签。

四、说明:............................... 错误!未定义书签。

五、设计要求:........................... 错误!未定义书签。

六、设计方案:........................... 错误!未定义书签。

七、流程图:............................. 错误!未定义书签。

八、运行结果............................. 错误!未定义书签。

九、源程序............................... 错误!未定义书签。

十、总结................................. 错误!未定义书签。

十一、参考文献........................... 错误!未定义书签。

四号黑体一、题目:(标题2,即三号黑体加粗)用多进程同步方法解决生产者-消费者问题。

二、设计目的:通过研究Linux 的进程机制和信号量实现生产者消费者问题的并发控制。

三、总体设计思想概述:1、生产者—消费者问题是一种同步问题的抽象描述。

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

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

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

四、说明:有界缓冲区内设有20个存储单元,放入/取出的数据项设定为1-20这20个整型数。

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

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

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

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

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

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

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

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

(1)间接制约。

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

(2)直接制约。

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

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

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

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

操作系统实验报告

操作系统实验报告

实验一(生产者—消费者)一.实验题目生产者与消费者实验二.实验目的加深进程的概念的理解,明确进程与程序的区别,深入认识程序并发执行的实质,理解进程竞争资源的现象,互斥与同步的基本概念,掌握相关的API的使用,了解多线程的并发执行机制,实现线程的同步与互斥的基本方法。

三.实验内容分析已编制的一个“生产者—消费者”实例,并将缺失的代码补充完整,然后调试这段程序,得出最终的结果,并分析此结果,得出相应的结论,尝试改变一些参数,分析这一改变对结果的影响。

四.设计思路和算法1.利用windows提供的API函数CreateSemaphore()创建信号量对象;Create Thread()创建线程;WaitForSingleObject()执行P操作;Release Semaphore()执行V操作;WaitForMultipleObjects()主进程等待线程的结束等函数进行设计。

2.在Windows中,常见的同步对象有:信号量(Semaphore)、互斥量(Mutex) 。

使用这些对象都分为三个步骤,一是创建或者初始化;接着请求该同步对象,随即进入临界区,这一步对应于互斥量的上锁;最后释放该同步对象,这对应于互斥量的解锁。

这些同步对象在主进程中创建,在其子线程中都可五.主要数据结构每个进程有一个进程控制块( PCB)表示。

进程控制块可以包含如下信息:进程类型标号、进程系统号、进程状态(本程序未用)、进程产品(字符)、进程链指针等等。

系统开辟了一个缓冲区,大小由buffersize指定。

程序中有三个链队列,一个链表。

一个就绪队列(ready),两个等待队列:生产者等待队列(producer);消费者队列(consumer)。

一个链表(over),用于收集已经运行结束的进程本程序通过函数模拟信号量的原子操作。

六.程序运行结果运行程序后的结果:生产者1准备生产生产者1开始往缓冲区中写数据生产者1开始退出缓冲区...生产者2准备生产生产者2开始往缓冲区中写数据生产者2开始退出缓冲区...消费者1准备消费消费者1开始消费缓冲区中数据消费者1开始退出缓冲区...生产者3准备生产生产者3开始往缓冲区中写数据生产者3开始退出缓冲区...消费者2准备消费消费者2开始消费缓冲区中数据消费者2开始退出缓冲区...生产者4准备生产生产者4开始往缓冲区中写数据生产者4开始退出缓冲区...消费者3准备消费消费者3开始消费缓冲区中数据消费者3开始退出缓冲区...生产者5准备生产生产者5开始往缓冲区中写数据生产者5开始退出缓冲区...消费者4准备消费消费者4开始消费缓冲区中数据消费者4开始退出缓冲区...生产者6准备生产生产者6开始往缓冲区中写数据生产者6开始退出缓冲区...消费者5准备消费消费者5开始消费缓冲区中数据消费者5开始退出缓冲区...生产者7准备生产生产者7开始往缓冲区中写数据生产者7开始退出缓冲区...消费者6准备消费消费者6开始消费缓冲区中数据消费者6开始退出缓冲区...生产者8准备生产生产者8开始往缓冲区中写数据生产者8开始退出缓冲区...消费者7准备消费消费者7开始消费缓冲区中数据消费者7开始退出缓冲区...生产者9准备生产生产者9开始往缓冲区中写数据生产者9开始退出缓冲区...消费者8准备消费消费者8开始消费缓冲区中数据消费者8开始退出缓冲区...生产者10准备生产生产者10开始往缓冲区中写数据生产者10开始退出缓冲区...消费者9准备消费消费者9开始消费缓冲区中数据消费者9开始退出缓冲区...消费者10准备消费消费者10开始消费缓冲区中数据消费者10开始退出缓冲区...七.源程序#include<>#include<>#include<>#include<string>#include<>#define MAX_BUFFER_NUM 10#define INTE_PER_SEC 1000#define MAX_THREAD_NUM 64strict ThreadInfo{into serial;char entity;double delay;into thread_request[MAX_THREAD_NUM];into n_request;};CRITICAL_SECTION PC_Critical[MAX_BUFFER_NUM];into Buffer_Critical[MAX_BUFFER_NUM]; HANDLE h_Thread[MAX_THREAD_NUM]; ThreadInfo Thread_Info[MAX_THREAD_NUM]; HANDLE empty_semaphore;HANDLE h_mutex;DWORD n_Thread = 0;DWORD n_Buffer_or_Critical;HANDLE h_Semaphore[MAX_THREAD_NUM];void Produce(void *p);void Consume(void *p);bool IfInOtherRequest(into);into FindProducePositon();into FindBufferPosition(into);into main(void){DWORD wait_for_all;ifstream inFile;for(into i=0;i< MAX_BUFFER_NUM;i++)Buffer_Critical[i] = -1;for(into j=0;j<MAX_THREAD_NUM;j++){for(into k=0;k<MAX_THREAD_NUM;k++)Thread_Info[j].thread_request[k] = -1;Thread_Info[j].n_request = 0;}for(i =0;i< MAX_BUFFER_NUM;i++)InitializeCriticalSection(&PC_Critical[i]); ("");inFile >> n_Buffer_or_Critical;();printf("输入文件是:\n");printf("%d \n",(into) n_Buffer_or_Critical);while(inFile){inFile >> Thread_Info[n_Thread].serial;inFile >> Thread_Info[n_Thread].entity;inFile >> Thread_Info[n_Thread].delay;char c;(c);while(c!='\n'&& !()){inFile>>Thread_Info[n_Thread].thread_request[Thread_Info[n_Thread].n_request++];(c);}n_Thread++;}for(j=0;j<(into) n_Thread;j++){into Temp_serial = Thread_Info[j].serial;char Temp_entity = Thread_Info[j].entity;double Temp_delay = Thread_Info[j].delay;printf(" \n 线程:%2d %c %f ",Temp_serial,Temp_entity,Temp_delay);into Temp_request = Thread_Info[j].n_request;for(into k=0;k<Temp_request;k++)printf(" %d ", Thread_Info[j].thread_request[k]);cout<<endl;}printf("\n\n");empty_semaphore=CreateSemaphore(NULL,n_Buffer_or_Critica l,n_Buffer_or_Critical,"semaphore_for_empty");h_mutex = CreateMutex(NULL,FALSE,"mutex_for_update");for(j=0;j<(into)n_Thread;j++){std::string lp ="semaphore_for_produce_";into temp =j;while(temp){char c = (char)(temp%10);lp+=c;temp/=10;}h_Semaphore[j+1]=CreateSemaphore(NULL,0,n_Thread,());}for(i =0;i< (into) n_Thread;i++){if(Thread_Info[i].entity =='P')h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Produce),&(Thread_Info[i]),0,NULL);elseh_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(C onsume),&(Thread_Info[i]),0,NULL);}wait_for_all = WaitForMultipleObjects(n_Thread,h_Thread,TRUE,-1);printf(" \n \n所有生产和消费已经完成他们的工作。

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

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

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

熟悉相关系统API的用法。

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

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

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

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

3个消费者, 重复4次。

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

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

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

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

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

操作系统实验报告-三大经典问题之生产者与消费者问题
计算机操作系统实验报告题目三大经典问题之生产者与消费者问题
一、课程设计的性质与任务
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个缓冲区的缓冲池,生产者进程将它所生产的产品放入一个缓冲区,消费者进程可从缓冲区中取走产品去消费,但它们之间必须保持同步,即不允许消费者进程到一个空缓冲区去取产品,也不允许生产者进程向一个已装满且尚未取出的缓冲区中投放产品,并且生产者消费者互斥使用缓冲区。

四、实验原理图
开始
Wait
Wait
Consu
Produce
While consume
While produce
结束
五、算法实现
(1)有一个生产者线程ProduceThread,有1个消费者进程CustomerThread;缓冲区为shareList。

(2)使用线程同步:用synchonized关键字(加锁)使得一个时间内只能有一个线程得到执行,另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块;wait()让线程进入等待状态;notify()函数唤醒一个处于等待状态的线程。

(3)程序运行流程图如下:(如不在外部中断,程序将一直循环运行)
开始
生产者 消费者 仓库是
否 是 消费者
消费者生产

生产者
唤醒消
唤醒生
六、源代码
package 操作系统;
/*
*产品类
*/
publicclass Goods {
int id;
String name;
public String toString(){
return id+" "+name;
}
}
package 操作系统;
importjava.util.List;
/*
* 消费者线程:有产品时可以取出,无产品时等待 */
publicclassCustomerThreadextends Thread{ privateListshareList;
CustomerThread(ListshareList){
this.shareList=shareList;
}
publicvoid run(){
System.out.println("消费线程已启动..."+shareList.size());
while(true){
try{
synchronized(shareList){
while(shareList.size()==0){
//如果没有产品,消费线程则等待
shareList.wait();
}
while(shareList.size()>0){
System.out.println("<---消费线程取出产品:"+shareList.remove(0).toString());
shareList.notify();
}
}
}catch(Exception ef){
ef.printStackTrace();
}
}
}
}
package 操作系统;
importjava.util.List;
/*
* 生产者线程:无数据时再存,存入一个要发通知
*/
publicclassProduceThreadextends Thread{ //构造器参数是生产线程要放入的队列
publicProduceThread(ListshareList){ this.shareList=shareList;
}
publicvoid run(){
System.out.println("生产线程已启动..."+shareList.size());
while(true){
try{
Thread.sleep(2000);
synchronized(shareList){
while(shareList.size()>0){
shareList.wait();
}
while(shareList.size()==0){
Goods gs = newGoods();
count++;
gs.id=count;
="产品"+count;
System.out.println("--->生产线程放入对象:"+gs.toString());
shareList.add(gs);
//通知消费线程,队列中有对象了
shareList.notify();
}
}
}catch(Exception ef){
ef.printStackTrace();
}
}
}
//用来标记放入对象的每一个独立ID号
privatestaticint count=0;
//与消费者线程或以共同存取的对象列表
privateListshareList;
}
package 操作系统;
importjava.util.LinkedList;
importjava.util.List;
public class Manage {
//主函数
public static void main(String[] args){
//生产\消费线程交换对象的队列
List shareList = new java.util.LinkedList();
//启动生产线程
newProduceThread(shareList).start();
//启动消费线程
newCustomerThread(shareList).start();
}
}
七、运行结果
八、实验心得
在此次实验中我们模拟PV 操作同步机构,来解决消费者与生产者这两个进程之间的同步协调问题。

实验中值得注意的是解决进程同步需要做哪些工作,如何利用信号量机制来解决进程同步问题等等。

通过本次实验,我对操作系统的p、v有了进一步认识,深入了解了p、v操作的实质和其重要性,加深了我对操作系统中多线
程机制的理解和认识,更让我认识到知识的掌握,仅靠学习理论知识是远远不够的,要与实际动手操作相结合才能更好地理解和分析问题。

此外,我也发现自己在编程上仍存在较大的问题,本次实验让我对java语言的线程编写水平有了提高。

我日后会不断加深各方面知识的学习,弥补自己的不足。

实验给了我们实践的机会,给了我们理论结合实际的机会,从实验中可以学到很多东西,不仅仅是书本上的东西这么简单,更是培养了我们动手能力和自学能力,还有更重要的是对待事情严谨的态度,我定会以更加严谨认真的态度对待每次实验。

相关文档
最新文档