用多线程同步方法解决生产者-消费者问题(操作系统课设)

合集下载

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

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

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

用多线程同步方法解决生产者-消费者问题

用多线程同步方法解决生产者-消费者问题

目录1.需求分析 (2)1.1 课程设计题目 (2)1.2 课程设计任务 (2)1.3 课程设计原理 (2)1.4 课程设计要求 (2)1.5 实验环境 (2)2. 概要设计 (3)2.1 课程设计方案概述 (3)2.2 课程设计流程图 (3)3.详细设计 (4)3.1 主程序模块 (4)3.2 生产者程序模块 (5)3.3 消费者程序模块 (6)4.调试中遇到的问题及解决方案 (6)5.运行结果 (7)6.实验小结 (7)参考文献 (8)附录:源程序清单 (8)1.需求分析1.1 课程设计题目用多线程同步方法解决生产者-消费者问题1.2 课程设计任务(1)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容、当前指针位置和生产者/消费者线程的标识符。

(2)生产者和消费者各有两个以上。

(3)多个生产者或多个消费者之间须共享对缓冲区进行操作的函数代码。

1.3 课程设计原理生产者和消费者问题是从操作系统中的许多实际同步问题中抽象出来的具有代表性的问题,它反映了操作系统中典型的同步例子,生产者进程(进程由多个线程组成)生产信息,消费者进程使用信息,由于生产者和消费者彼此独立,且运行速度不确定,所以很可能出现生产者已产生了信息而消费者却没有来得及接受信息这种情况。

为此,需要引入由一个或者若干个存储单元组成的临时存储区(即缓冲区),以便存放生产者所产生的信息,解决平滑进程间由于速度不确定所带来的问题。

1.4 课程设计要求(1)有界缓冲区内设有20个存储单元,放入/取出的数据项设定为1~20这20个整型数。

(2)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容、当前指针位置和生产者/消费者线程的标识符。

(3)生产者和消费者各有两个以上。

(4)多个生产者或多个消费者之间须共享对缓冲区进行操作的函数代码。

1.5 实验环境系统平台:LINUX开发语言:C开发工具:PC机一台2. 概要设计2.1 课程设计方案概述本设计中设置一个长度为20的一维数组buff[20]作为有界缓冲区,缓冲区为0时,代表该缓冲区内没有产品,buff[i]=i+1表示有产品,产品为i+1。

操作系统中的经典问题——生产者消费者问题(两种方式实现)

操作系统中的经典问题——生产者消费者问题(两种方式实现)

操作系统中的经典问题——⽣产者消费者问题(两种⽅式实现)操作系统中的经典问题——⽣产者消费者问题(两种⽅式实现)1、问题引⼊:什么是⽣产者消费者问题?⽣产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是⼀个多线程同步问题的经典案例。

该问题描述了共享固定⼤⼩缓冲区的两个线程——即所谓的“⽣产者”和“消费者”——在实际运⾏时会发⽣的问题。

⽣产者的主要作⽤是⽣成⼀定量的数据放到缓冲区中,然后重复此过程。

与此同时,消费者也在缓冲区消耗这些数据。

该问题的关键就是要保证⽣产者不会在缓冲区满时加⼊数据,消费者也不会在缓冲区中空时消耗数据。

.要解决该问题,就必须让⽣产者在缓冲区满时休眠(要么⼲脆就放弃数据),等到下次消费者消耗缓冲区中的数据的时候,⽣产者才能被唤醒,开始往缓冲区添加数据。

同样,也可以让消费者在缓冲区空时进⼊休眠,等到⽣产者往缓冲区添加数据之后,再唤醒消费者。

通常采⽤进程间通信的⽅法解决该问题。

如果解决⽅法不够完善,则容易出现死锁的情况。

出现死锁时,两个线程都会陷⼊休眠,等待对⽅唤醒⾃⼰。

该问题也能被推⼴到多个⽣产者和消费者的情形。

2、问题分析该问题需要注意的⼏点:1. 在缓冲区为空时,消费者不能再进⾏消费2. 在缓冲区为满时,⽣产者不能再进⾏⽣产3. 在⼀个线程进⾏⽣产或消费时,其余线程不能再进⾏⽣产或消费等操作,即保持线程间的同步4. 注意条件变量与互斥锁的顺序由于前两点原因,因此需要保持线程间的同步,即⼀个线程消费(或⽣产)完,其他线程才能进⾏竞争CPU,获得消费(或⽣产)的机会。

对于这⼀点,可以使⽤条件变量进⾏线程间的同步:⽣产者线程在product之前,需要wait直⾄获取⾃⼰所需的信号量之后,才会进⾏product的操作;同样,对于消费者线程,在consume之前需要wait直到没有线程在访问共享区(缓冲区),再进⾏consume的操作,之后再解锁并唤醒其他可⽤阻塞线程。

操作系统课程设计“生产者-消费者”问题

操作系统课程设计“生产者-消费者”问题

《操作系统》课程设计题目:“生产者-消费者”问题学院:信息工程学院专业:计算机科学与技术班级:计科1302*名:***指导老师:***2016年1月 15日目录一、课程设计目标 (2)二、课题内容 (2)1.实验目的 (2)2、实验环境 (2)3、实验要求 (2)三、设计思路 (3)1.信号量的设置 (3)2.系统结构 (4)3.程序流程图 (5)4.P V操作代码 (6)四、源代码 (7)五、运行与测试 (10)六、心得体会 (12)一、课程设计目标学习System V的进程间通信机制,使用信号量和共享内存实现经典进程同步问题“生产者-消费者”问题。

具体要求:1.创建信号量集,实现同步互斥信号量。

2.创建共享内存,模拟存放产品的公共缓冲池。

3.创建并发进程,实现进程对共享缓冲池的并发操作。

二、课题内容1.实验目的(1)掌握基本的同步互斥算法,理解生产者和消费者同步的问题模型。

(2)了解linux中多线程的并发执行机制,线程间的同步和互斥。

2、实验环境:C/C++语言编译器3、实验要求(1)创建生产者和消费者线程在linux环境下,创建一个控制台进程,在此进程中创建n个线程来模拟生产者或者消费者。

这些线程的信息由本程序定义的“测试用例文件”中予以指定。

(2)生产和消费的规则在按照上述要求创建线程进行相应的读写操作时,还需要符合以下要求:①共享缓冲区存在空闲空间时,生产者即可使用共享缓冲区。

②从上边的测试数据文件例子可以看出,某一生产者生产一个产品后,可能不止一个消费者,或者一个消费者多次地请求消费该产品。

此时,只有当所有的消费需求都被满足以后,该产品所在的共享缓冲区才可以被释放,并作为空闲空间允许新的生产者使用。

③每个消费者线程的各个消费需求之间存在先后顺序。

例上述测试用例文件包含一行信息“5 C 3 l 2 4”,可知这代表一个消费者线程,该线程请求消费1,2,4号生产者线程生产的产品。

而这种消费是有严格顺序的,消费1号线程产品的请求得到满足后才能继续往下请求2号生产者线程的产品。

多进程同步方法演示“生产者-消费者”问题

多进程同步方法演示“生产者-消费者”问题

青岛理工大学操作系统课程设计报告院(系):计算机工程学院专业:计算机科学与技术专业学生姓名:__班级:_______学号:题目:用多进程同步方法演示“生产者-消费者”问题起迄日期:设计地点:指导教师:年度第学期完成日期: 年月日一、课程设计目的本次进行操作系统课程设计的主要任务是设计一个模拟生产者消费者工作的系统。

这个问题中有一种生产者和一种消费者,生产者和消费者对同一个缓冲区进行操作,互斥的访问缓冲区。

本次课程设计的目的就是加深对多进程如何正确访问资源的认识,同时掌握信号量在互斥访问时应该如何正确有效地使用。

掌握生产者消费者问题的解决流程和方法,提高编程能力、解决问题的能力和查阅文档的能力。

二、课程设计内容与要求1、设计目的:通过研究Linux的进程同步机制和信号量,实现生产者消费者问题的并发控制。

2、说明:有界缓冲区内设有20个存储单元,放入取出的产品设定为20个100以内的随机整数。

3、设计要求:1)生产者与消费者均有二个以上2)生产者和消费者进程的数目在程序界面上可调,在运行时可随时单个增加与减少生产者与消费者3)生产者的生产速度与消费者的消费速度均可在程序界面调节,在运行中,该值调整后立即生效4)生产者生产的产品由随机函数决定5)多个生产者或多个消费者之间必须有共享对缓冲区进行操作的函数代码6)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容、当前生产者与消费者的指针位置,以及生产者和消费者线程标识符7)采用可视化界面,可在运行过程中随时暂停,查看当前生产者、消费者以及有界缓冲区的状态三、系统分析与设计1、系统分析系统分析1.此次课程设计的任务是生产者消费者问题的模拟演示,需要处理的数据有:生产者进程数目,消费者进程数目,生产者生产速度,消费者消费速度,缓冲区中产品的个数,以及生产、消费产品的指针。

2.程序中需要缓冲区中的信息可以动态演示,生产者、消费者的个数以及生产、消费时的速度可以随时调节,同时为了使程序更加友好,应该具有开始、暂停、停止等相关可操作按钮。

用多线程同步方法解决生产者-消费者问题操作系统课设

用多线程同步方法解决生产者-消费者问题操作系统课设

学号:课程设计题目用多线程同步方法解决生产者-消费者问题(Producer-Consumer Problem)学院计算机科学与技术学院专业软件工程班级姓名指导教师年月日目录目录 (1)课程设计任务书 (1)正文 (2)1.设计目的与要求 (2)1.1设计目的 (2)1.2设计要求 (2)2.设计思想及系统平台 (2)2.1设计思想 (2)2.2系统平台及使用语言 (2)3.详细算法描述 (3)4.源程序清单 (5)5.运行结果与运行情况 (10)6.调试过程 (13)7.总结 (13)本科生课程设计成绩评定表 ..................................................... 错误!未定义书签。

课程设计任务书学生姓名:专业班级:指导教师:工作单位:计算机科学与技术学院题目: 用多线程同步方法解决生产者-消费者问题(Producer-Consumer Problem)初始条件:1.操作系统:Linux2.程序设计语言:C语言3.有界缓冲区内设有20个存储单元,其初值为0。

放入/取出的数据项按增序设定为1-20这20个整型数。

要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.技术要求:1)为每个生产者/消费者产生一个线程,设计正确的同步算法2)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的当前全部内容、当前指针位置和生产者/消费者线程的自定义标识符。

3)生产者和消费者各有两个以上。

4)多个生产者或多个消费者之间须共享对缓冲区进行操作的函数代码。

2.设计说明书内容要求:1)设计题目与要求2)总的设计思想及系统平台、语言、工具等。

3)数据结构与模块说明(功能与流程图)4)给出用户名、源程序名、目标程序名和源程序及其运行结果。

(要注明存储各个程序及其运行结果的主机IP地址和目录。

)5)运行结果与运行情况(提示: (1)有界缓冲区可用数组实现。

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

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

实验报告二实验名称:一、生产者-消费者问题的多线程解决方案二、设计一个执行矩阵乘法的多线程程序日期: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 Runnableprivate 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.在多线程矩阵开发实验中,刚开始定义矩阵太小,测试结果不太明显,后面通过把矩阵改大,并且线程数目不断变化使得结果明显。

操作系统课程设计用多进程同步方法解决生产者 消费者问题1word文档良心出品

操作系统课程设计用多进程同步方法解决生产者 消费者问题1word文档良心出品
未定义书签。
未定义书签。
未定义书签。
未定义书签。
未定义书签。
.错.误!未定义书签。
.错.误!未定义书签。
.3...
.5...
.2..0.
、题目:
用多进程同步方法ห้องสมุดไป่ตู้决生产者-消费者问题。
掌握信号量机制的过程。
掌握c语言编程。
通过研究Linux的进程机制和信号量实现生产者消费者问题的并发控制。
资源时,可以看作是消耗,且该进程称为消费者。
操作系统课程设计
用多进程同步方法解决生产者-消费者问题
别:
计算机科学与技术
级:
04级4班

号:
名:
间:
2006-7-7—2006-7-14
一、题目:
二、设计目的:
三、总体设计思想概述:
四、说明:
五、设计要求:
六、设计方案:
七、流程图:
八、运行结果
九、源程序
十、总结
一、参考文献
.错.误!
.错.误!
.错.误!

生产者消费者问题 操作系统课程设计

生产者消费者问题 操作系统课程设计

生产者消费者问题操作系统课程设计生产者消费者问题是操作系统中常见的一个并发问题,本课程设计旨在帮助学生深入理解该问题及其解决方案。

课程设计内容包括:
1. 生产者消费者问题的定义、特点和解决方案
2. 生产者消费者问题的算法设计与实现
3. 多线程并发编程实践
4. 操作系统调度与同步机制实践
5. 生产者消费者问题的应用场景与案例分析
通过本课程设计,学生将能够掌握操作系统中的重要问题与解决方案,并具备多线程并发编程的实践技能,为以后的操作系统开发与应用打下坚实的基础。

- 1 -。

Linux下实现多线程的生产者消费者问题

Linux下实现多线程的生产者消费者问题

Linux下实现多线程的生产者消费者问题一、原理的理解生产者-消费者问题是一个经典的线程同步问题,该问题最早由Dijkstra提出,用以演示他提出的信号量机制。

在同一个线程地址空间内执行的两个线程。

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

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

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

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

多个生产/消费者在有界缓冲上操作。

它利用N个字节的共享内存作为有界循环缓冲区,利用写一字符模拟放一个产品,利用读一字符模拟消费一个产品。

当缓冲区空时消费者应阻塞睡眠,而当缓冲区满时生产者应当阻塞睡眠。

一旦缓冲区中有空单元,生产者线程就向空单元中入写字符,并报告写的内容和位置。

一旦缓冲区中有未读过的字符,消费者线程就从该单元中读出字符,并报告读取位置。

生产者不能向同一单元中连续写两次以上相同的字符,消费者也不能从同一单元中连续读两次以上相同的字符。

二、完成步骤1、思路分析本作业是完善课件上的线程综合实例的练习生产者-消费者问题,重构这个程序的框架,完成性能分析,使之进一步理解掌握Linux下线程的同步、通信以及互斥和多线程的安全问题。

一般情况下,解决互斥方法常用信号量和互斥锁,即semaphore和mutex,而解决这个问题,多采用一个类似资源槽的结构,每个槽位标示了指向资源的指针以及该槽位的状态,生产者和消费者互斥查询资源槽,判断是否有产品或者有空位可以生产,然后根据指针进行相应的操作。

同时,为了告诉生产者或者消费者资源槽的情况,还要有一个消息传送机制,无论是管道还是线程通信。

然而,本次试验有几个特殊的要求:A、循环缓冲。

B、除了stderr,stdout等外,只用小于2个的互斥锁、C、放弃资源槽分配机制,采用额外的数据结构。

多线程生产者消费者问题处理

多线程生产者消费者问题处理

多线程⽣产者消费者问题处理⼀、⽐较低级的办法是⽤wait和notify来解决这个问题。

消费者⽣产者问题:这个问题是⼀个多线程同步问题的经典案例,⽣产者负责⽣产对象,消费者负责将⽣成者产⽣的对象取出,两者不断重复此过程。

这过程需要注意⼏个问题:不论⽣产者和消费者有⼏个,必须保证:1.⽣产者每次产出的对象必须不⼀样,产⽣的对象有且仅有出现⼀次;2.消费者每次取出的对象必须不⼀样,取出的对象有且仅有出现⼀次;3.⼀定是先产⽣该对象,然后对象才能被取出,顺序不能乱;第⼀种情况:多个⽣产者轮流负责⽣产,多个消费者负责取出。

⼀旦⽣产者产⽣⼀个对象,其他⽣产者不能⽣产,只能由消费者执⾏取出操作;需要的对象有商品类、消费者、⽣产者;//测试类public class ProducerConsumer {public static void main(String[] args) {// 定义资源对象Resource r = new Resource();//定义⼀个⽣产者和⼀个消费者Producer p = new Producer(r);Consumer c = new Consumer(r);//启动四个线程,2个负责⽣产者,两个消费者Thread t1 = new Thread(p);Thread t2 = new Thread(p);Thread t3 = new Thread(c);Thread t4 = new Thread(c);t1.start();t2.start();t3.start();t4.start();}}//商品类class Resource{private String name;private int count = 1;private boolean flag = false;//产⽣商品public synchronized void set(String name) {while (flag) {try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}} = name + "---" + count++;System.out.println(Thread.currentThread().getName() + " ⽣产者" + );flag = true;//唤醒所有线程this.notifyAll();}//取出商品public synchronized void out() {while (!flag) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName() + " 消费者________" + );flag = false;this.notifyAll();}}//定义⽣产者class Producer implements Runnable{private Resource res;public Producer(Resource res) {this.res = res;}@Overridepublic void run() {while (true) {res.set("+商品+");}}}//定义消费者class Consumer implements Runnable{private Resource res;Consumer(Resource res) {this.res = res;}@Overridepublic void run() {while (true) {res.out();}}}运⾏结果是产⽣⼀个,随即取出⼀个,循环往复,其运⾏结果的部分如下:Thread-2 消费者________+商品+---67821Thread-1 ⽣产者+商品+---67822Thread-3 消费者________+商品+---67822Thread-0 ⽣产者+商品+---67823Thread-2 消费者________+商品+---67823Thread-1 ⽣产者+商品+---67824Thread-3 消费者________+商品+---67824Thread-0 ⽣产者+商品+---67825Thread-2 消费者________+商品+---67825Thread-1 ⽣产者+商品+---67826Thread-3 消费者________+商品+---67826Thread-0 ⽣产者+商品+---67827Thread-2 消费者________+商品+---67827Thread-1 ⽣产者+商品+---67828Thread-3 消费者________+商品+---67828Thread-0 ⽣产者+商品+---67829Thread-2 消费者________+商品+---67829Thread-1 ⽣产者+商品+---67830Thread-3 消费者________+商品+---67830Thread-0 ⽣产者+商品+---67831Thread-2 消费者________+商品+---67831Thread-1 ⽣产者+商品+---67832第⼆种情况:⽬标:⽣产者与消费者轮换着抢夺执⾏权,但是⽣产者最多可以库存5个,消费者最多可以连续取出5个此时需要定义⼀种中间对象:仓库类。

操作系统课程设计用多进程同步方法解决生产者-消费者问题

操作系统课程设计用多进程同步方法解决生产者-消费者问题

操作系统课程设计用多进程同步方法解决生产者-消费者问题系别:计科系专业: 计算机科学与技术班级: 04 级 4 班学号: 0410*******姓名:苏德洪时间: 2006-7-7—2006-7-14目录一、题目: 3二、设计目的: 3三、总体设计思想概述: 3四、说明: 3五、设计要求: 3六、设计方案: 3七、流程图: 5八、运行结果 7九、源程序 11十、总结 19十一、参考文献 20一、题目:用多进程同步方法解决生产者-消费者问题。

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

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

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

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

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

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

五、设计要求:1、每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容,当前指针位置和生产者/消费者线程的标识符。

2、生产者和消费者各有两个以上。

3、多个生产者或多个消费者之间须有共享对缓冲区进行操作的函数代码。

六、设计方案:通过一个有界缓冲区(用数组来实现,类似循环队列)把生产者和消费者联系起来。

假定生产者和消费者的优先级是相同的,只要缓冲区未满,生产者就可以生产产品并将产品送入缓冲区。

类似地,只要缓冲区未空,消费者就可以从缓冲区中去走产品并消费它。

应该禁止生产者向满的缓冲区送入产品,同时也应该禁止消费者从空的缓冲区中取出产品,这一机制有生产者线程和消费者线程之间的互斥关系来实现。

为解决生产者/消费者问题,应该设置两个资源信号量,其中一个表示空缓冲区的数目,用g_hFullSemaphore表示,其初始值为有界缓冲区的大小SIZE_OF_BUFFER;另一个表示缓冲区中产品的数目,用g_hEmptySemaphore表示,其初始值为0。

多进程同步方法解决生产者-消费者问题

多进程同步方法解决生产者-消费者问题

课程设计报告课程名称:操作系统实验题目:用多进程同步方法解决生产者-消费者问题院系:计算机科学与工程学院班级:姓名:学号:指导老师:一、概述:1、问题描述:用多进程同步方法解决生产者-消费者问题设计目的:通过研究Linux 的进程机制和信号量实现生产者消费者问题的并发控制.说明:有界缓冲区内设有20个存储单元,放入/取出的数据项设定为1-20这20个整型数.设计要求:1) 每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容,当前指针位置和生产者/消费者线程的标识符.2) 生产者和消费者各有两个以上.3) 多个生产者或多个消费者之间须有共享对缓冲区进行操作的函数代码.2、程序设计基本思想:生产者—消费者问题是一种同步问题的抽象描述。

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

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

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

一个有限空间的共享缓冲区,负责存放货物。

生产者向缓冲区中放物品,缓冲区满则不能放。

消费者从缓冲区中拿物品,缓冲区空则不能拿。

因为有多个缓冲区,所以生产者线程没有必要在生成新的数据之前等待最后一个数据被消费者线程处理完毕。

同样,消费者线程并不一定每次只能处理一个数据。

在多缓冲区机制下,线程之间不必互相等待形成死锁,因而提高了效率。

多个缓冲区就好像使用一条传送带替代托架,传送带上一次可以放多个产品。

生产者在缓冲区尾加入数据,而消费者则在缓冲区头读取数据。

当缓冲区满的时候,缓冲区就上锁并等待消费者线程读取数据;每一个生产或消费动作使得传送带向前移动一个单位,因而,消费者线程读取数据的顺序和数据产生顺序是相同的。

可以引入一个count计数器来表示已经被使用的缓冲区数量。

用Producer和Consumer 来同步生产者和消费者线程。

每当生产者线程发现缓冲区满( count=BufferSize ),它就等待Consumer事件。

多进程同步方法解决生产者-消费者问题

多进程同步方法解决生产者-消费者问题
架,传送带上一次可以放多个产品。生产者在缓冲区尾加入数据,而消费者则在缓冲区头读取数据。当缓冲区满的时候,缓冲区就上锁并等待消费者线程读取数据;每一个生产或消费动作使得传送带向前移动一个单位,因而,消费者线程读取数据的顺序和数据产生顺序是相同的。
可以引入一个count计数器来表示已经被使用的缓冲区数量。用Producer和Consumer来同步生产者和消费者线程。每当生产者线程发现缓冲区满(count=BufferSize),它就等待Consumer事件。同样,当消费者线程发现缓冲区空,它就开始等待Producer。生产者线程写入一个新的数据之后,就立刻发出Consumer来唤醒正在等待的消费者线程;消费者线程在读取一个数据之后,就发出Producer来唤醒正在等待的生产者线程。
通过一个有界缓冲区(用数组来实现,类似循环队列)把生产者和消费者联系起来。假定生产者和消费者的优先级是相同的,只要缓冲区未满,生产者就可以生产产品并将产品送入缓冲区。类似地,只要缓冲区未空,消费者就可以从缓冲区中去走产品并消费它。应该禁止生产者向满的缓冲区送入产品,同时也应该禁止消费者从空的缓冲区中取出产品,这一机制有生产者线程和消费者线程之间的互斥关系来实现。

m个生产者、k个消费者、共享n个单元缓冲区
基本算法如下:

4.1、生产者流程结构:
4.2消费者流程结构:

a)用一个整型数组Buffer_NUM来代表缓冲区。生产产品及对已有产品消费都需要访问该组缓冲区。
缓冲区的大小和结构体:
struct Buffer
{
int product[BUFFER_NUM]; //缓冲区
int start, end; //两个指针相当于教材中的in out指针

(完整版)操作系统毕业课程设计用多进程同步方法解决生产者-消费者问

(完整版)操作系统毕业课程设计用多进程同步方法解决生产者-消费者问

操作系统课程设计用多进程同步方法解决生产者-消费者问题系别:计科系专业: 计算机科学与技术班级:.04级4班姓名:. 苏德洪目录一、题目:.................................................... 3.. .二、设计目的:.................................................... 3.. .三、总体设计思想概述:............................. 3..四、说明:.................................................... 3.. .五、设计要求:.................................................... 3.. .六、设计方案:.................................................... 3.. .七、流程图:.................................................... 5...八、运行结果.................................................... 7.. .九、源程序 (11)十、总结................................................... 1..9 ..十一、参考文献................................................... 2..0 .一、题目:用多进程同步方法解决生产者- 消费者问题。

二、设计目的:掌握信号量机制的过程。

掌握 c 语言编程。

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

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

生产者-消费者问题(进程同步问题)

生产者-消费者问题(进程同步问题)

⽣产者-消费者问题(进程同步问题)最近在学线程,在加上操作系统也在学线程,于是乎有了这篇⽂章问题描述:⼀群⽣产者进程在⽣成产品,并将这些产品提供给消费者进程去消费. 他们之间有⼀个公共的缓冲区⽤来存放产品,当产品为空时消费者不能消费,当产品为满时⽣产者不能⽣产CPP实现利⽤mutex 互斥量来对缓存区的操作进⾏加锁#include <chrono>#include <iostream>#include <mutex>#include <thread>constexpr int n = 10; // 缓存区⼤⼩int in = 0, out = 0; // ⽣产指针,消费指针int full = 0, empty = 10; // 空与满int buffer[10]; // 缓存区std::mutex mtx; // 互斥量/*** ⽣产者函数*/void producer() {do {while (full == n);std::this_thread::sleep_for(std::chrono::seconds(1));{std::scoped_lock lock(mtx);buffer[in] = 1;in = (in + 1) % n;std::cout << "⽣产者⽣产:" << in << "\n";empty--;full++;}} while (true);}/*** 消费者函数*/void consumer() {do {while (empty == n);{std::scoped_lock lock(mtx);buffer[out] = 0;out = (out + 1) % n;std::cout << "消费者消费:" << out << "\n";empty++;full--;}std::this_thread::sleep_for(std::chrono::seconds(2));} while (true);}int main() {std::thread t1{producer};std::thread t2{consumer};t1.join();t2.join();return 0;}Java实现⽤Storage对象模拟缓存区,关键代码如下/*** 存储类*/public class Storage {private Product[] products = new Product[10];private int top = 0;public synchronized void push(Product product){while(top == products.length){try{System.out.println("producer wait");wait(); //缓冲区满,⽆法⽣产,则阻塞}catch (InterruptedException e){e.printStackTrace();}}products[top++] = product;System.out.println(Thread.currentThread().getName()+" ⽣产了 "+product); System.out.println("producer notifyAll");notifyAll(); //⽣产出新的产品,唤醒消费者进程}public synchronized Product pop(){while (top==0){try{System.out.println("consumer wait");;wait(); //缓冲区空,⽆法消费,阻塞}catch (InterruptedException e){e.printStackTrace();}}--top;Product p = new Product(products[top].getId(),products[top].getName()); products[top] = null;System.out.println(Thread.currentThread().getName()+ " 消费了 "+p);System.out.println("consumer notifyAll");notifyAll(); //消费了产品,唤醒⽣产者return p;}}public class Producer implements Runnable{private Storage storage;public Producer(Storage storage){this.storage = storage;}@Overridepublic void run() {int i=0;Random r = new Random();while(i<10){i++;Product product = new Product(i,"电话"+r.nextInt(100));storage.push(product);}}}public class Consumer implements Runnable{private Storage storage;public Consumer(Storage storage){this.storage = storage;}@Overridepublic void run() {int i=0;while (i<10){i++;storage.pop();try {Thread.sleep(1000);}catch (InterruptedException e){e.printStackTrace();} } }}。

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

.题目用多线程同步方法解决生产者-消费者问题(Producer-Consumer Problem)学院计算机科学与技术学院专业软件工程班级姓名指导教师年月日目录目录 (1)课程设计任务书 (2)正文 (2)1.设计目的与要求 (2)1.1设计目的 (2)1.2设计要求 (2)2.设计思想及系统平台 (2)2.1设计思想 (2)2.2系统平台及使用语言 (2)3.详细算法描述 (3)4.源程序清单 (7)5.运行结果与运行情况 (13)6.调试过程 (17)7.总结 (17)本科生课程设计成绩评定表 (18)课程设计任务书学生姓名:专业班级:指导教师:工作单位:计算机科学与技术学院题目: 用多线程同步方法解决生产者-消费者问题(Producer-Consumer Problem)初始条件:1.操作系统:Linux2.程序设计语言:C语言3.有界缓冲区内设有20个存储单元,其初值为0。

放入/取出的数据项按增序设定为1-20这20个整型数。

要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.技术要求:1)为每个生产者/消费者产生一个线程,设计正确的同步算法2)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的当前全部内容、当前指针位置和生产者/消费者线程的自定义标识符。

3)生产者和消费者各有两个以上。

4)多个生产者或多个消费者之间须共享对缓冲区进行操作的函数代码。

2.设计说明书内容要求:1)设计题目与要求2)总的设计思想及系统平台、语言、工具等。

3)数据结构与模块说明(功能与流程图)4)给出用户名、源程序名、目标程序名和源程序及其运行结果。

(要注明存储各个程序及其运行结果的主机IP地址和目录。

)5)运行结果与运行情况(提示: (1)有界缓冲区可用数组实现。

(2)编译命令可用:cc -lpthread -o 目标文件名源文件名(3)多线程编程方法参见附件。

)3. 调试报告:1)调试记录2)自我评析和总结上机时间安排:18周一~ 五08:0 -12:00指导教师签名:年月日系主任(或责任教师)签名:年月日正文1.设计目的与要求1.1设计目的通过研究Linux的线程机制和信号量实现生产者消费者问题(Producer-Consumer Problem)的并发控制。

1.2设计要求1)为每个生产者/消费者产生一个线程,设计正确的同步算法2)每个生产者/消费者对该存储区进行操作后,即时显示该存储区的全部内容、当前指针位置和生产者/消费者线程的自定义标识符。

3)生产者和消费者各有两个以上。

4)多个生产者/消费者之间须共享对存储区进行操作的函数代码。

2.设计思想及系统平台2.1设计思想在本问题中,共需要一个Mutex和两个Semaphore.其中,Mutex是用来锁定临界区的,以解决对共享数据buffer的互斥访问问题(无论是对生成者还是对消费者);我们共需要两个Semaphore,这是因为在本问题中共有两个稀缺资源.第一种是"非空"这种资源,是在消费者之间进行竞争的.第二种是"非满"这种资源,是在生产者之间进行竞争的.所以,一般来说,需要锁定临界区,就需要Mutex;有几种稀缺资源就需要几个Semaphore.对稀缺资源的分析不能想当然.稀缺资源不一定是指被共享的资源,很多时候是指线程会被阻塞的条件(除了要进临界区被阻塞外).在生产者消费者问题中,消费者会在缓冲区为空时被阻塞,所以"非空"是一种稀缺资源; 需要设置一个信号量consumer_semaphore,初值设为0;生产者会在缓冲区为满时被阻塞,所以"非满"也是一种稀缺资源.需要设置一个信号量producer_semaphore,初值设为buffer的大小MAX_BUFFER 2.2系统平台及使用语言本课程设计在Linux操作系统下,使用C语言完成。

用到的工具主要有GCC编译器和VI编辑器。

3.详细算法描述共享数据:Semaphore buffer_mutex=1;Semaphore producer_semaphore=MAX_BUFFER;Semaphore consumer_semaphore=0;int buffer[MAX_BUFFER];Producer线程的处理函数:while(1){Wait(producer_semaphore);Wait(buffer_mutex);Buffer[pn]=product;pn=(pn+1)%MAX_BUFFER;Signal(consumer_semaphore);Signal(buffer_mutex);Sleep();}producer线程的处理函数流程图如下:consumer线程的处理函数: while(1){Wait(consumer_semaphore); Wait(buffer_mutex); Consume=buffer[cn];cn=(cn+1)%MAX_BUFFER; Signal(producer_semaphore); Signal(buffer_mutex);Sleep();}consumer线程的处理函数流程图如下:4.源程序清单用户名:rj070126(IP:192.168.2.254)源程序名:/home/rj070126/pc.c目标程序名:/home/rj070126/pc运行结果:/home/rj070126/output.txt源程序清单如下:#include<stdio.h>#include<stdlib.h>#include<string.h>#include<pthread.h>#include<semaphore.h>#include<sys/types.h>#include<errno.h>#include<unistd.h>#include<signal.h>#include<time.h>#define NUM_THREADS_P 5 /*define the number of producer*/ #define NUM_THREADS_C 5 /*define the number of consumer*/ #define MAX_BUFFER 20 /*define the number of buffer*/#define RUN_TIME 20 /*define the run time*/int buffer[MAX_BUFFER]; /*difine the buffer */int produce_pointer=0,consume_pointer=0;sem_t producer_semaphore,consumer_semaphore,buffer_mutex; pthread_t threads_p[NUM_THREADS_P]; /*producer*/pthread_t threads_c[NUM_THREADS_C]; /*consumer*/FILE* fd;void *producer_thread(void *tid);void *consumer_thread(void *tid);void showbuf();void handler(){int i;for(i=0;i<NUM_THREADS_P;i++)pthread_cancel(threads_p[i]);for(i=0;i<NUM_THREADS_C;i++)pthread_cancel(threads_c[i]);}int main(){int i;signal(SIGALRM,handler);fd=fopen("output.txt","w"); /*open a file to save the result*/sem_init(&producer_semaphore,0,MAX_BUFFER); /*set the value of semaphores*/ sem_init(&consumer_semaphore,0,0);sem_init(&buffer_mutex,0,1);for(i=0;i<MAX_BUFFER;i++)buffer[i]=0; /*initiate the buffer*//*create the threads*/for(i=0;i<NUM_THREADS_P;i++)pthread_create(&threads_p[i],NULL,(void*)producer_thread,(void*)(i+1));for(i=0;i<NUM_THREADS_C;i++)pthread_create(&threads_c[i],NULL,(void*)consumer_thread,(void *)(i+1)); alarm(RUN_TIME); /*set time to run*//*wait the threads to exit*/for(i=0;i<NUM_THREADS_P;i++)pthread_join(threads_p[i],NULL);for(i=0;i<NUM_THREADS_C;i++)pthread_join(threads_c[i],NULL);/*destroy the semaphores*/sem_destroy(&producer_semaphore);sem_destroy(&consumer_semaphore);sem_destroy(&buffer_mutex);fclose(fd);return 0;}void *producer_thread(void *tid){/*the thread can be canceled by other thread*/pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);while(1){sem_wait(&producer_semaphore);srand((int)time(NULL)*(int)tid);sleep(rand()%2+1); /*one or two seconds to produce*/while((produce_pointer+1)%20==consume_pointer);sem_wait(&buffer_mutex);buffer[produce_pointer]=rand()%20+1;produce_pointer=(produce_pointer+1)%20;if(produce_pointer==0){ /*if buffer was filled to the 19th*/printf("producer:%d pointer_p:%2d produced:%2d\n",(int)tid,19,buffer[19]);fprintf(fd,"producer:%d pointer_p:%2d produced:%2d\n",(int)tid,19,buffer[19]);}else{printf("producer:%d pointer_p:%2d produced:%2d\n",(int)tid,produce_pointer-1,buffer[produce_pointer-1]);fprintf(fd,"producer:%d pointer_p:%2d produced:%2d\n",(int)tid,produce_pointer-1,buffer[produce_pointer-1]);}showbuf();sem_post(&buffer_mutex);sem_post(&consumer_semaphore); /*inform the consumer the buffer is not empty*/srand((int)time(NULL)*(int)tid);sleep(rand()%5+1); /*wait a few seconds ,then continue producing*/ }return ((void*)0);}void *consumer_thread(void *tid){/*the thread can be canceled by other thread*/pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);while(1){sem_wait(&consumer_semaphore);srand((int)time(NULL)*(int)tid);sleep(rand()%2+1); /*one or two seconds to consume*/sem_wait(&buffer_mutex);printf("consumer:%d pointer_c:%2d consumed:%2d\n",(int)tid,consume_pointer,buffer[consume_pointer]);fprintf(fd,"consumer:%d pointer_c:%2d consumed:%2d\n",(int)tid,consume_pointer,buffer[consume_pointer]);buffer[consume_pointer]=0;consume_pointer=(consume_pointer+1)%20;showbuf();sem_post(&buffer_mutex);sem_post(&producer_semaphore);srand((int)time(NULL)*(int)tid);sleep(rand()%5+1); /*wait a few seconds ,then continue consuming*/ }return ((void*)0);}/*show the content of buffer*/void showbuf(){int i;printf("buffer:");fprintf(fd,"buffer:");for(i=0;i<MAX_BUFFER;i++){printf("%2d ",buffer[i]);fprintf(fd,"%2d ",buffer[i]);}printf("\n\n");fprintf(fd,"\n\n");}5.运行结果与运行情况程序运行结果如下:producer:1 pointer_p: 0 produced:20buffer:20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0producer:3 pointer_p: 1 produced:13buffer:20 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0producer:2 pointer_p: 2 produced: 6buffer:20 13 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0producer:4 pointer_p: 3 produced:14buffer:20 13 6 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0producer:5 pointer_p: 4 produced:20buffer:20 13 6 14 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0consumer:2 pointer_c: 0 consumed:20buffer: 0 13 6 14 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0producer:1 pointer_p: 5 produced:20buffer: 0 13 6 14 20 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0consumer:1 pointer_c: 1 consumed:13buffer: 0 0 6 14 20 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0consumer:3 pointer_c: 2 consumed: 6buffer: 0 0 0 14 20 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0consumer:4 pointer_c: 3 consumed:14buffer: 0 0 0 0 20 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0consumer:5 pointer_c: 4 consumed:20buffer: 0 0 0 0 0 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0producer:3 pointer_p: 6 produced: 1buffer: 0 0 0 0 0 20 1 0 0 0 0 0 0 0 0 0 0 0 0 0producer:2 pointer_p: 7 produced:14buffer: 0 0 0 0 0 20 1 14 0 0 0 0 0 0 0 0 0 0 0 0consumer:3 pointer_c: 5 consumed:20buffer: 0 0 0 0 0 0 1 14 0 0 0 0 0 0 0 0 0 0 0 0producer:4 pointer_p: 8 produced: 6buffer: 0 0 0 0 0 0 1 14 6 0 0 0 0 0 0 0 0 0 0 0consumer:5 pointer_c: 6 consumed: 1buffer: 0 0 0 0 0 0 0 14 6 0 0 0 0 0 0 0 0 0 0 0producer:5 pointer_p: 9 produced: 8buffer: 0 0 0 0 0 0 0 14 6 8 0 0 0 0 0 0 0 0 0 0consumer:2 pointer_c: 7 consumed:14buffer: 0 0 0 0 0 0 0 0 6 8 0 0 0 0 0 0 0 0 0 0consumer:5 pointer_c: 8 consumed: 6buffer: 0 0 0 0 0 0 0 0 0 8 0 0 0 0 0 0 0 0 0 0producer:1 pointer_p:10 produced:18buffer: 0 0 0 0 0 0 0 0 0 8 18 0 0 0 0 0 0 0 0 0 consumer:1 pointer_c: 9 consumed: 8buffer: 0 0 0 0 0 0 0 0 0 0 18 0 0 0 0 0 0 0 0 0producer:2 pointer_p:11 produced:10buffer: 0 0 0 0 0 0 0 0 0 0 18 10 0 0 0 0 0 0 0 0producer:4 pointer_p:12 produced:10buffer: 0 0 0 0 0 0 0 0 0 0 18 10 10 0 0 0 0 0 0 0consumer:4 pointer_c:10 consumed:18buffer: 0 0 0 0 0 0 0 0 0 0 0 10 10 0 0 0 0 0 0 0producer:3 pointer_p:13 produced: 3buffer: 0 0 0 0 0 0 0 0 0 0 0 10 10 3 0 0 0 0 0 0consumer:3 pointer_c:11 consumed:10buffer: 0 0 0 0 0 0 0 0 0 0 0 0 10 3 0 0 0 0 0 0consumer:2 pointer_c:12 consumed:10buffer: 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0producer:1 pointer_p:14 produced: 6buffer: 0 0 0 0 0 0 0 0 0 0 0 0 0 3 6 0 0 0 0 0consumer:1 pointer_c:13 consumed: 3buffer: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 0 0 0 0 0producer:2 pointer_p:15 produced:18buffer: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 18 0 0 0 0consumer:5 pointer_c:14 consumed: 6buffer: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 0 0 0 0producer:1 pointer_p:16 produced: 6buffer: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 6 0 0 0producer:3 pointer_p:17 produced:19buffer: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 6 19 0 0consumer:1 pointer_c:15 consumed:18buffer: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 19 0 0producer:5 pointer_p:18 produced: 7buffer: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 19 7 0consumer:3 pointer_c:16 consumed: 6buffer: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19 7 0producer:4 pointer_p:19 produced:14buffer: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19 7 14consumer:5 pointer_c:17 consumed:19buffer: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 14consumer:4 pointer_c:18 consumed: 7buffer: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14producer:1 pointer_p: 0 produced: 4buffer: 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14consumer:2 pointer_c:19 consumed:14buffer: 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0consumer:1 pointer_c: 0 consumed: 4buffer: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0producer:2 pointer_p: 1 produced:15buffer: 0 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0producer:3 pointer_p: 2 produced:13buffer: 0 15 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0producer:2 pointer_p: 3 produced: 3buffer: 0 15 13 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0说明:“producer:2”是指自定义标号为2的producer,“pointer_p:3”是指该producer的指针,“produced:3”是指该producer在buffer[3]里写入3,“buffer: 0 15 13 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ”是指该producer进行写操作后存储区的内容。

相关文档
最新文档