生产者消费者问题c操作系统实验报告范文三大问题之生产者与消费者问题
- 格式:docx
- 大小:38.68 KB
- 文档页数:7
操作系统实验三:生产者——消费者问题一、基本信息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 操作。
实验报告二实验名称:一、生产者-消费者问题的多线程解决方案二、设计一个执行矩阵乘法的多线程程序日期: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.在多线程矩阵开发实验中,刚开始定义矩阵太小,测试结果不太明显,后面通过把矩阵改大,并且线程数目不断变化使得结果明显。
操作系统课程设计一.实验目标完成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。
操作系统生产者消费者问题实验报告实验名称:一、生产者-消费者问题的多线程解决方案二、设计一个执行矩阵乘法的多线程程序日期:20XX-10-22 班级:13级计科学号:姓名:一、实验目的1.掌握线程的同步与互斥2.掌握生产者消费者的实现问题3.掌握多线程的编程方法4.掌握矩阵乘法的基本计算原理以及实现二、实验内容1.生产者-消费者问题的多线程解决方案2.设计一个执行矩阵乘法的多线程程序三、项目要求与分析1.请查阅资料,掌握线程创建的相关知识以及矩阵乘法的相关知识,了解java语言程序编写的相关知识2.理解线程的实验步骤在本次试验中,以“生产者-消费者”模型为依据,提供了一个多线程的“生产者-消费者”实例,编写java代码调试运行结果,得出相应的结论。
理解矩阵乘法的实验步骤四、具体实现1.生产者-消费者实例(1)创建一个缓冲信息发送接收通道接口,并创建邮箱盒子类实现,主要代码如下://通道接口public interface Channel{public abstract void send(Object item);public abstract Object receive();}//实现接口public class MessageQueue implements Channel{private Vector queue;public MessageQueue(){queue=new Vector();}public void send(Object item){queue.addElement(ite m);}public Object receive(){if(queue.size()==0)return null;elsereturn queue.remove(0);}}(2)创建一个工厂多线程类(启动生产者和消费者),并且添加main 函数进行测试,主要代码如下://工厂类与主方法public class Factory{public Factory(){Channel mailBox=new MessageQueue();Thread producerThread=new Thread(new Producer(mailBox));Thread consumerThread=new Thread(new Consumer(mailBox));producerThread.start();consumerThread.start();}public static void main(String[] args){Factory server=new Factory();}(3)创建一个线程睡眠类,用于测试,主要代码如下:public class SleepUtilities{public static void nap(){nap(NAP_TIME);}public static void nap(int duration){int sleeptime = (int)(NAP_TIME * Math.random());try{ Thread.sleep(sleeptime*1000); }catch (InterruptedException e) {}}private static final int NAP_TIME = 5;(4)创建生产者类实现Runnable,主要代码如下:public class Producer implements Runnable{private Channel mbox;public Producer(Channel mbox){this.mbox=mbox;}public void run(){Date message;while(true){SleepUtilities.nap();message=new Date();System.out.println("Producer produced "+message);mbox.send(message);}}}(5)创建消费者类实现Runnable,主要代码如下:public class Consumer implements Runnable{private Channel mbox;public Consumer(Channel mbox){this.mbox=mbox;}public void run(){Date message;while(true){SleepUtilities.nap();message=(Date)mbox.receive();if(message!=null)System.out.println("Consumer consumed "+message);}}}(6)调试程序,运行结果:2.矩阵乘法实例(1)初始化矩阵(便于观察,这里使用随机数生成矩阵),主要初始化代码如下matrix1 = new int[m][k];matrix2 = new int[k][n];matrix3 = new int[m][n];//随机初始化矩阵a,bfillRandom(matrix1);fillRandom(matrix2);static void fillRandom(int[][] x){for (int i=0; i<x.length; i++){for(int j=0; j<x[i].length; j++){//每个元素设置为0到99的随机自然数x[i][j] = (int) (Math.random() * 100);}}}(2)打印输出矩阵函数,主要代码如下:static void printMatrix(int[][] x){for (int i=0; i<x.length; i++){for(int j=0; j<x[i].length; j++) {System.out.print(x[i][j]+" ");}System.out.println("");}System.out.println("");}(3)创建多线程类,并实现Runnable接口同步对矩阵进行分行计算,主要代码如下://创建线程,数量 <= 4for(int i=0; i<4; i++){if(index < m){Thread t = new Thread(new MyThread());t.start();}else{break;}synchronized static int getTask(){if(index < m){return index++;}return -1;}}class MyThread implements Runnable{int task;//@Overridepublic void run(){MultiThreadMatrix.threadCount++;while( (task= MultiThreadMatrix.getTask()) != -1 ){System.out.println("进程:"+Thread.currentThread().getName()+"\t开始计算第"+(task+1)+"行");for(int i=0; i<MultiThreadMatrix.n; i++){for(int j=0; j<MultiThreadMatrix.k;j++){MultiThreadMatrix.matrix3[task][i] += MultiThreadMatrix.matrix1[task][j] *MultiThreadMatrix.matrix2[j][i];}}}MultiThreadMatrix.threadCount--;}(4)通过不断改变矩阵大小,线程数目,,调试程序,运行结果:五、所遇问题与解决方法1.在生产者-消费者多线程试验中,刚开始没有考虑到使用线程睡眠,运行结果速度之快,没法观看数据变化,后面定义了睡眠控制,使得问题得以解决2.在多线程矩阵开发实验中,刚开始定义矩阵太小,测试结果不太明显,后面通过把矩阵改大,并且线程数目不断变化使得结果明显。
生产者消费者问题实验报告生产者消费者问题实验报告一、引言生产者消费者问题是计算机科学中一个经典的并发问题,主要涉及到多个线程之间的协作和资源的共享。
在本实验中,我们通过编写一个简单的程序来模拟生产者和消费者之间的交互过程,以深入理解该问题的本质和解决方案。
二、问题描述在生产者消费者问题中,有两类线程:生产者和消费者。
生产者线程负责生产一定数量的产品,而消费者线程则负责消费这些产品。
两类线程需要共享一个有限的缓冲区,生产者将产品放入缓冲区,而消费者从缓冲区中取出产品。
然而,缓冲区的容量是有限的,当缓冲区已满时,生产者需要等待,直到有空间可用。
同样地,当缓冲区为空时,消费者需要等待,直到有产品可用。
三、实验设计为了解决生产者消费者问题,我们采用了经典的解决方案——使用互斥锁和条件变量。
互斥锁用于保护共享资源的访问,保证同一时间只有一个线程可以访问共享资源。
而条件变量用于线程之间的通信,当某个条件不满足时,线程可以通过条件变量进入等待状态,直到条件满足时再被唤醒。
在我们的程序中,我们使用了一个有界缓冲区来模拟生产者消费者之间的交互。
缓冲区的大小可以通过参数进行设置。
我们创建了两个线程分别代表生产者和消费者,它们通过互斥锁和条件变量来实现同步。
生产者线程在缓冲区未满时将产品放入缓冲区,并通知消费者线程有产品可用;消费者线程在缓冲区非空时从缓冲区取出产品,并通知生产者线程有空间可用。
通过这种方式,我们保证了生产者和消费者之间的协作和资源的共享。
四、实验结果经过多次运行实验,我们观察到了以下现象:当生产者线程的生产速度大于消费者线程的消费速度时,缓冲区会被生产者填满,消费者需要等待;当消费者线程的消费速度大于生产者线程的生产速度时,缓冲区会被消费者清空,生产者需要等待。
只有当生产者和消费者的速度相等时,才能实现平衡的生产和消费。
此外,我们还发现在某些情况下,生产者和消费者线程可能出现死锁或饥饿现象。
死锁是指两个或多个线程相互等待对方释放资源,导致程序无法继续执行的情况。
第1篇一、实验目的1. 加深对进程概念的理解,明确进程和程序的区别。
2. 进一步认识并发执行的实质。
3. 验证用信号量机制实现进程互斥的方法。
4. 验证用信号量机制实现进程同步的方法。
二、实验环境1. 操作系统:Windows 102. 编程语言:C语言3. 开发工具:Visual Studio三、实验内容1. 生产者和消费者模型介绍生产者和消费者模型是操作系统中常见的一种并发控制模型,用于解决多个进程之间的同步和互斥问题。
在该模型中,生产者负责生成数据,消费者负责消费数据。
生产者和消费者通过共享资源(如缓冲区)进行通信。
2. 实验设计(1)环形缓冲区为了实现生产者和消费者的同步,我们设计了一个环形缓冲区,由若干个大小相等的缓冲块组成。
每个缓冲块可以容纳一个产品。
环形缓冲区的指针分别指向当前的第一个空缓冲块和第一个满缓冲块。
(2)信号量为了实现进程互斥和同步,我们使用了三个信号量:① 公用信号量:用于实现临界区互斥,初始值为1。
② 生产者私用信号量:用于实现生产者与消费者之间的同步,初始值为0。
③ 消费者私用信号量:用于实现生产者与消费者之间的同步,初始值为0。
(3)生产者进程生产者进程负责生成数据,并将数据存入环形缓冲区。
当环形缓冲区满时,生产者进程等待;当环形缓冲区有空位时,生产者进程继续生成数据。
(4)消费者进程消费者进程负责从环形缓冲区中取出数据并消费。
当环形缓冲区空时,消费者进程等待;当环形缓冲区有数据时,消费者进程继续消费数据。
3. 实验步骤(1)创建生产者进程和消费者进程。
(2)初始化信号量。
(3)运行生产者进程和消费者进程。
(4)按任意键停止程序,显示当前系统的各个参数的值。
四、实验结果与分析1. 实验结果通过运行实验程序,我们可以观察到生产者和消费者进程的运行情况。
当按下任意键停止程序时,程序将显示当前系统的各个参数的值,包括环形缓冲区的空位数量、生产者和消费者的状态等。
2. 分析(1)互斥:通过公用信号量实现生产者和消费者对环形缓冲区的互斥访问,防止了同时操作缓冲区的问题。
操作系统实验报告——生产者和消费者问题姓名:学号:班级:一、实验内容1、模拟操作系统中进程同步和互斥;2、实现生产者和消费者问题的算法实现;二、实验目的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;}。
实验报告(学生打印后提交)实验名称: 生产者和消费者问题实验时间: 2023年 5 月 5日●实验人员:●实验目的:掌握基本的同步互斥算法, 理解生产者和消费者模型。
●了解Windows 2023/XP中多线程的并发执行机制, 线程间的同步和互斥。
●学习使用Windows 2023/XP中基本的同步对象, 掌握相应的API●实验环境: WindowsXP + VC++6.0●运用Windows SDK提供的系统接口(API, 应用程序接口)完毕程序的功能。
API是操作系统提供的用来进行应用程序设计的系统功能接口。
使用API, 需要包含对API函数进行说明的SDK头文献, 最常见的就是windows.h实验环节:1.读懂源程序.2.编辑修改源程.......................................实验陈述:1.基础知识:本实验用到几个API函数:CreateThread CreateMutex, WaitForSingleObject, ReleaseMutexCreateSemaphore, WaitForSingleObject, ReleaseSemaphore, ReleaseMutex, nitializeCriticalSection, EnterCriticalSection, LeaveCriticalSection。
这些函数的作用:CreateThread, 功能:创建一个线程, 该线程在调用进程的地址空间中执行。
CreateMutex,功能:产生一个命名的或者匿名的互斥量对象。
WaitForSingleObject(相应p操作)锁上互斥锁, ReleaseMutex(相应v操作)打开互斥锁.。
CreateSemaphore, 创建一个命名的或者匿名的信号量对象。
信号量可以看作是在互斥量上的一个扩展。
WaitForSingleObject, 功能:使程序处在等待状态, 直到信号量(或互斥量)hHandle出现或者超过规定的等待最长时间, 信号量出现指信号量大于或等于1, 互斥量出现指打开互斥锁。
操作系统上机实验报告实验名称:生产者与消费者问题模拟实验目的:通过模拟生产者消费者问题理解进程或线程之间的同步与互斥。
实验内容:1、设计一个环形缓冲区,大小为10,生产者依次向其中写入1到20,每个缓冲区中存放一个数字,消费者从中依次读取数字。
2、相应的信号量;3、生产者和消费者可按如下两种方式之一设计;(1)设计成两个进程;(2)设计成一个进程内的两个线程。
4、根据实验结果理解信号量的工作原理,进程或线程的同步\互斥关系。
实验步骤及分析:一.管道(一)管道定义所谓管道,是指能够连接一个写进程和一个读进程的、并允许它们以生产者—消费者方式进行通信的一个共享文件,又称为pipe文件。
由写进程从管道的写入端(句柄1)将数据写入管道,而读进程则从管道的读出端(句柄0)读出数据。
(二)所涉及的系统调用1、pipe( )建立一无名管道。
系统调用格式pipe()参数定义int pipe();int [2];其中,[1]是写入端,[0]是读出端。
该函数使用头文件如下:#include <unistd.h>#inlcude <signal.h>#include <stdio.h>2、read( )系统调用格式:read(fd,buf,nbyte)功能:从fd所指示的文件中读出nbyte个字节的数据,并将它们送至由指针buf所指示的缓冲区中。
如该文件被加锁,等待,直到锁打开为止。
参数定义:int read(fd,buf,nbyte);int fd;char *buf;unsigned nbyte;3、write( )系统调用格式read(fd,buf,nbyte)功能:把nbyte 个字节的数据,从buf所指向的缓冲区写到由fd所指向的文件中。
如文件加锁,暂停写入,直至开锁。
参数定义同read( )。
(三)参考程序#include <unistd.h>#include <signal.h>#include <stdio.h>int pid1,pid2;main( ){int fd[2];char outpipe[100],inpipe[100];pipe(fd); /*创建一个管道*/while ((pid1=fork( ))==-1);if(pid1==0){lockf(fd[1],1,0);/*把串放入数组outpipe中*/sprintf(outpipe,"child 1 is using pipe!");/*向管道写长为50字节的串*/write(fd[1],outpipe,50);sleep(5); /*自我阻塞5秒*/lockf(fd[1],0,0);exit(0);}else{while((pid2=fork( ))==-1);if(pid2==0){lockf(fd[1],1,0); /*互斥*/sprintf(outpipe,"child 2 is using pipe!");write(fd[1],outpipe,50);sleep(5);lockf(fd[1],0,0);exit(0);}else{wait(0); /*同步*/read(fd[0],inpipe,50);/*从管道中读长为50字节的串*/printf("%s\n",inpipe);wait(0);read(fd[0],inpipe,50);printf("%s\n",inpipe);exit(0);}}}编写过程:运行结果:二、信号机制(一)信号的基本概念每个信号都对应一个正整数常量(称为signal number,即信号编号。
第一篇:操作系统实验报告经典生产者—消费者问题实验二经典的生产者—消费者问题一、目的实现对经典的生产者—消费者问题的模拟,以便更好的理解经典进程同步问题。
二、实验内容及要求编制生产者—消费者算法,模拟一个生产者、一个消费者,共享一个缓冲池的情形。
1、实现对经典的生产者—消费者问题的模拟,以便更好的理解此经典进程同步问题。
生产者-消费者问题是典型的PV 操作问题,假设系统中有一个比较大的缓冲池,生产者的任务是只要缓冲池未满就可以将生产出的产品放入其中,而消费者的任务是只要缓冲池未空就可以从缓冲池中拿走产品。
缓冲池被占用时,任何进程都不能访问。
2、每一个生产者都要把自己生产的产品放入缓冲池,每个消费者从缓冲池中取走产品消费。
在这种情况下,生产者消费者进程同步,因为只有通过互通消息才知道是否能存入产品或者取走产品。
他们之间也存在互斥,即生产者消费者必须互斥访问缓冲池,即不能有两个以上的进程同时进行。
三、生产者和消费者原理分析在同一个进程地址空间内执行两个线程。
生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。
消费者线程从缓冲区中获得物品,然后释放缓冲区。
当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放一个空缓冲区。
当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻挡,直到新的物品被生产出来。
四、生产者与消费者功能描述:生产者功能描述:在同一个进程地址空间内执行两个线程。
生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。
当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。
消费者功能描述:消费者线程从缓冲区获得物品,然后释放缓冲区,当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。
五、实验环境操作系统环境:Windows 系统。
编程语言:C#。
《操作系统课程设计》实验报告生产者消费者问题2013年12 月25 日一设计目标运用条件变量和互斥锁原理实现线程同步问题,解决生产者消费者问题1.1 背景知识说明在Linux环境下需要使用POSIX库进行设计实现,POSIX是Portable Operating System Interface of Unix的缩写。
由IEEE(Institute of Electrical and Electronic Engineering)开发,由ANSI和ISO 标准化。
POSIX的诞生和Unix的发展是密不可分的,Unix于70年代诞生于贝尔实验室,并于80年代向美各大高校分发V7版的源码以做研究。
加利福尼亚大学伯克利分校在V7的基础上开发了BSD Unix。
后来很多商业厂家意识到Unix的价值也纷纷以贝尔实验室的System V或BSD 为基础来开发自己的Unix,较著名的有Sun OS,AIX,VMS。
文档收集自网络,仅用于个人学习基于posix的线程标准库是pthreadPOSIX线程(POSIX Thread),简称Pthread,是线程的POSIX 标准。
该标准定义了创建和操纵线程的一整套API。
在类Unix操作系统(Unix、Linux、Mac OS X等)中,都使用Pthread作为操作系统的线程。
Windows操作系统也有其移植版pthread-win32。
文档收集自网络,仅用于个人学习Pthreads定义了一套C语言的类型、函数与常量,它以pthread.h头文件和一个线程库实现。
1.2 原理在同一个进程地址空间内执行的两个线程生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。
消费者线程从缓冲区中获得物品,然后释放缓冲区。
当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。
当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。
中南大学操作系统实验报告实验内容:Java多线程模拟生产者消费者问题实验时间:2014年5月指导老师:胡小龙老师姓名:代巍班级:信安1201班学号:**********一、实验目的对操作系统的整体进行一个模拟,通过实践加深对各个部分的管理功能的认识,还能进一步分析各个部分之间的联系,最后达到对完整系统的理解。
可以提高运用操作系统知识解决实际问题的能力;锻炼实际的编程能力,要达到以下要求。
(1)掌握进程(线程)的同步与互斥。
(2)掌握生产者消费者问题的实现方法。
(3)掌握多线程编程方法。
二、实验内容实现生产者消费者问题。
(1)假设循环缓冲队列共有多个缓冲单元。
(2)生产者线程的工作:生产出一个产品(即产生一个产品编号),按顺序往缓冲队列中“空”的缓冲单元放产品。
(3)消费者线程与的工作:从缓冲队列装有产品的缓冲单元中取出一个产品(即产品编号)。
(4)保证两个线程间的互斥和同步(5)在界面上打印缓冲队列的变化情况三、实验原理(1)生产者—消费者问题是一种同步问题的抽象描述。
(2)计算机系统中的每个进程都可以消费或生产某类资源。
当系统中某一进程使用某一资源时,可以看作是消耗,且该进程称为消费者。
(3)而当某个进程释放资源时,则它就相当一个生产者。
模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介。
生产者把数据放入缓冲区,而消费者从缓冲区取出数据。
大概的结构如下图。
四、实验思想概述在操作系统中,线程有时被称为轻量级进程,是CPU使用的基本单位,它与属于同一进程的其他进程共享其他代码段、数据段和其他操作系统资源。
在Java中,线程的建立有两种方法:继承Thread类和实现Runnable接口。
其中,采用实现Runnable接口建立线程的好处是允许同时继承其他类从而实现多继承,并且在Java中,可采用synchronized或Object类的方法wait(),notify(),notifyAll()来实现多线程同步。
实验一生产者和消费者问题1、程序流程图2、源代码#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 << " ... ";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;}3、实验结果3、实验心得通过做生产者消费者问题这个实验,让我更加明确了两者之间的联系和基本的同步互斥算法,了解多线程并发执行机制是怎样的,线程间的同步和互斥又是怎样的,还有缓冲区的在其中作用是什么。
计算机操作系统实验报告题目三大经典问题之生产者与消费者问题一、课程设计的性质与任务1、加深对并发协作进程同步与互斥概念的理解。
通过编写程序实现进程同步和互斥,使学生掌握有关进程(线程)同步与互斥的原理,以及解决进程(线程)同步和互斥的算法,从而进一步巩固进程(线程)同步和互斥等有关的容。
2、掌握进程和线程的概念,进程(线程)的控制原语或系统调用的使用。
3、了解Windows2000/XP中多线程的并发执行机制,线程间的同步和互斥。
学习使用Windows2000/XP中基本的同步对象,掌握相应的API函数。
4、培养学生能够独立进行知识综合,独立开发较大程序的能力。
5、培养提高学生软件开发能力和软件的调试技术。
6、培养学生开发大型程序的方法和相互合作的精神。
7、培养学生的创新意识。
8、培养学生的算法设计和算法分析能力。
9、培养学生对问题进行文字论述和文字表达的能力。
二、课程设计的容及其要求在Windows XP、Windows2000等操作系统下,使用的VC、VB、Java或C等编程语言,采用进程(线程)同步和互斥的技术编写程序实现生产者消费者问题或哲学家进餐问题或读者-写者问题或自己设计一个简单进程(线程)同步和互斥的实际问题。
要求:(1)经调试后程序能够正常运行。
(2)采用多进程或多线程方式运行,体现了进程(线程)同步互斥的关系。
(3)程序界面美观。
三、实验原理本实验要求利用PV操作实现解决生产者——消费者问题中的同步问题。
此问题描述的是一群生产者进程在生产产品并将这些产品提供给消费者进程去消费,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者进程将它所生产的产品放入一个缓冲区,消费者进程可从缓冲区中取走产品去消费,但它们之间必须保持同步,即不允许消费者进程到一个空缓冲区去取产品,也不允许生产者进程向一个已装满且尚未取出的缓冲区中投放产品,并且生产者消费者互斥使用缓冲区。
四、实验原理图五、算法实现(1)有一个生产者线程ProduceThread,有1个消费者进程CustomerThread;缓冲区为shareList。
实验三编程模拟生产者和花费者问题一、实验目的和要求模拟实现用同步机构防止发生进度履行时可能出现的与时间相关的错误。
进度是程序在一个数据会合上运转的过程,进度是并发履行的,也即系统中的多个进度轮番地占用办理器运转。
我们把若干个进度都能进行接见和改正的那些变量称为公共变量。
因为进度是并发地履行的,因此,假如对进度接见公共变量不加限制,那么就会产生“与时间相关” 的错误,即进度履行后所获取的结果与接见公共变量的时间相关。
为了防备这种错误,系统一定要用同步机构来控制进度对公共变量的接见。
一般说,同步机构是由若干条原语——同步原语——所构成。
本实习要修业生模拟 PV操作同步机构的实现,模拟进度的并发履行,认识进度并发履行时同步机构的作用。
二、实验环境Windows操作系统和 Visual C++ 专业版或公司版三、实验步骤模拟 PV操作同步机构,且用PV操作解决生产者——花费者问题。
[提示]:(1)PV操作同步机构,由 P 操作原语和 V 操作原语构成,它们的定义以下:P 操作原语 P (s) :将信号量 s 减去 1,若结果小于 0,则履行原语的进度被置成等候信号量s 的状态。
V 操作原语 V (s) :将信号量 s 加 1,若结果不大于 0,则开释一个等候信号量 s 的进度。
这两条原语是以下的两个过程:procedure p (var s: semaphore);begin s: = s-1;if s<0 then W (s)end {p}procedure v (var s: semaphore);egin s: = s+1;if s£0 then R (s)end {v}此中 W(s)表示将调用过程的进度置为等候信号量s 的状态; R(s)表示开释一个等候信号量s 的进度。
在系统初始化时应把semaphore 定义为某个种类,为简单起见,在模拟实习中可把上述的 semaphore 直接改成 integer 。
生产者消费者问题c操作系统实验报告范文三大问题之
生产者与消费者问题
计算机操作系统实验报告
一、课程设计的性质与任务
1、加深对并发协作进程同步与互斥概念的理解。
通过编写程序实现进程同步和互斥,使学生掌握有关进程(线程)同步与互斥的原理,以及解决进程(线程)同步和互斥的算法,从而进一步巩固进程(线程)同步和互斥等有关的内容。
2、掌握进程和线程的概念,进程(线程)的控制原语或系统调用的使用。
3、了解Window2000/某P中多线程的并发执行机制,线程间的同步和互斥。
学习使用Window2000/某P中基本的同步对象,掌握相应的API 函数。
4、培养学生能够独立进行知识综合,独立开发较大程序的能力。
5、培养提高学生软件开发能力和软件的调试技术。
6、培养学生开发大型程序的方法和相互合作的精神。
7、培养学生的创新意识。
&培养学生的算法设计和算法分析能力。
9、培养学生对问题进行文字论述和文字表达的能力。
二、课程设计的内容及其要求
在Window某P、Window2000等操作系统下,使用的VCVB、
Java或C等编程语言,采用进程(线程)同步和互斥的技术编写程序实现生产者消费者问题或哲学家进餐问题或读者-写者问题或自己设计一个简单进程(线程)同步和互斥的实际问题。
要求:(1)经调试后程序能够正常运行。
否
否
(2)采用多进程或多线程方式运行,体现了进程(线程)同步互斥的关系。
(3)程序界面美观。
三、实验原理
本实验要求利用PV操作实现解决生产者一一消费者问题中的同步问题。
此问题描述的是一群生产者进程在生产产品并将这些产品提供给消费者进程去消费,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者进程将它所生产的产品放入一个缓冲区,消费者进程可从缓冲区中取走产品去消费,但它们之间必须保持同步,即不允许消费者进程到一个空缓冲区去取产品,也不允许生产者进程向一个已装满且尚未取出的缓冲区中投放产品,并且生产者消费者互斥使用缓冲区。
四、实验原理图
五、算法实现
有一个生产者线程ProduceThread,有1个消费者进程CutomerThread;缓冲区为hareLit。
使用线程同步:用ynchonized关键字(加锁)使得一个时间内只能有一个线程得到执行,另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块;wait()让线程进入等待状态;notify()函数唤醒一个处于等待状态的线程。
程序运行流程图如下::(如不在外部中断,程序将一直循环运行)开始
生产者消费者
生产者
仓库是否
生产者生
消费者等
消费者消
唤醒消费
唤醒生产
六、源代码
package操作系统;
/某
某产品类
publicclaGood{
intid;
Stringname;
publicStringtoString(){
returnid+""+name;
package操作系统;
import
/某
某消费者线程:有产品时可以取出,无产品时等待某/
publicclaCutomerThreade某tendThread{ privateLithareLit:
CutomerThread(LjthareLit){
=hareLit;
}
publicvoidrun(){
"消费线程已启动..."+());
while(true){
ynchronized(hareLit){
while()==0){
oString());
();
}
}
}catch(E某ceptionef){
();
}
}
}
}
package操作系统;
import
/某
某生产者线程:无数据时再存,存入一个要发通知某/
publicclaProduceThreade某tendThread{
."+());
while(true){
try{
(2000);
ynchronized(hareLit){
while()>0){
();
}
while()==0){
Goodg=newGood();
count++;
=count;
="产品"+count;
"--->生产线程放入对象:"+());
(g);
tart();
tart();
七、运行结果
八、实验心得
在此次实验中我们模拟PV操作同步机构,来解决消费者与生产者这两个进程之间的同步协调问题。
实验中值得注意的是解决进程同步需要做哪些工作,如何利用信号量机制来解决进程同步问题等等。
通过本次实验,我对操作系统的p、v有了进一步认识,深入了解了p、v操作的实质和其重要性,加深了我对操作系统中多线程机制的理解和认识,更让我认识到知识的掌握,仅靠学习理论知识是远远不够的,要与实际动手操作相结合才能更好地理解和分析问题。
此外,我也发现自己在编程上仍存在较大的问题,本次实验让我对java语言的线程编写水平有了提高。
我日后会不断加深各方面知识的学习,弥补自己的不足。
实验给了我们实践的机会,给了我们理论结合实际的机会,从实验中可以学到很多东西,不仅仅是书本上的东西这么简单,更是培养了我们动手能力和自学能力,还有更重要的是对待事情严谨的态度,我定会以更加严谨认真的态度对待每次实验。