生产者和消费者问题是从操作系统中的许多实际同步问题中抽象出来的具有
代表性的问题。它反映了操作系统中典型的同步例子.
生产者进程(进程由多个线程组成)生产信息,例如它可以是计算进程。消费
者进程使用信息,它可以是输出打印进程。由于生产者和消费者彼此独立,且运
行速度不确定,所以很可能出现生产者已产生了信息而消费者却没有来得及接受
信息这种情况。为此,需要引入由一个或者若干个存储单元组成的临时存储区,
以便存放生产者所产生的信息,平滑进程间由于速度不确定所带来的问题。这个
临时存储区叫做缓冲区,通常用一维数组来表示。
由一个或若干个存储单元组成的缓冲区叫作“有穷缓冲区”。下面我们来分
析一下有穷缓冲的生产者和消费者的例子。
假设有多个生产者和多个消费者,它们共享一个具有n个存储单元的有穷缓冲
区Buffer(0……n-1),这是一个环形队列。其队尾指针Rear指向当前信息应存放
的位置(Buffer[Rear]),队首指针Front指向当前取出信息的位置(Buffer[front
])。生产者进程总是把信息存放在Buffer[Rear]中,消费者进程则总是从Buffer
[Rear]中取出信息。如果想使生产者进程和消费者进程协调合作,则必须使它们
遵循如下规则:
1) 只要缓冲区有存储单元,生产者都可往其中存放信息;当缓冲区已满时,
若任意生产者提出写要求,则都必须等待;
2) 只要缓冲区中有消息可取,消费者都可从缓冲区中取出消息;当缓冲区为
空时,若任意消费者想取出信息,则必须等待;
3) 生产者们和消费者们不能同时读、写缓冲区。
用JAVA 实现“生产者-消费者”问题的代码如下:
//----------------------------------------------------
// 商品
class Goods {
private int id;
public Goods(int id) { this.id = id; }
public String toString() {
return "Goods: " + id;
}
}
//----------------------------------------------------
// 装东西的容器
class Stack {
private int index = 0;
private Goods[] buffer = new Goods[5]; // 生产者和消费者共享的有界缓冲区
public synchronized void push(Goods goods) {
while(index == buffer.length) {
try {
this.wait();
} catch (InterruptedException e) { e.printStackTrace(); }
}
this.notify();
buffer[index] = goods;
index++;
}
public synchronized Goods pop() {
while(index == 0) {
try {
this.wait();
} catch (InterruptedException e) { e.printStackTrace(); }
}
this.notify();
index--;
return buffer[index];
}
}
//----------------------------------------------------
// 生产者线程
class Producer implements Runnable {
private Stack s = null;
public Producer(Stack s) { this.s = s; }
public void run() {
for(int i = 0; i <= 10; i++) {
Goods g = new Goods(i);
s.push(g);
System.out.println("生产了 " + g);
try {
Thread.sleep(1000);
} catch (InterruptedException e) { e.printStackTrace(); }
}
}
}
//----------------------------------------------------
// 消费者线程
class Consumer implements Runnable {
private Stack s = null;
public Consumer(Stack s) { this.s = s; }
public void run() {
for(int i = 0; i <= 10; i++) {
Goods g = s.pop();
System.out.println("消费了 " + g);
try {
Thread.sleep(1000);
} catch (InterruptedException e) { e.printStackTrace(); }
}
}
}
//----------------------------------------------------
// 主方法
public class ProducerConsumer {
public static void main(String[] args) {
Stack s = new Stack();
Producer p = new Producer(s);
Consumer c = new Consumer(s);
new Thread(p).start();
new Thread(c).start();
}
}
分享到:
相关推荐
使用信号量实现有限缓冲区的生产者和消费者问题 使用信号量实现读进程具有优先权的读者和写者问题
生产者和消费者问题以及哲学家就餐问题,JAVA实现的程序.rar产者和消费者问题以及哲学家就餐问题,JAVA实现的程序.rar
模拟PV操作同步机构,且用PV操作解决生产者——消费者问题。
使用信号量实现有限缓冲区的生产者和消费者问题 使用信号量实现读进程具有优先权的读者和写者问题 实验报告(内容、环境、遇到的问题及解决、源代码、流程图、总结) 源代码
实验一 生产者和消费者问题 因为源码比较长,所以想在网上找现成的,不想自己写,结果找了好久,发现:第一,《操作系统实验指导》基本上找不到电子版的;第二,这个实验的源码也很难找(反正我是没找到,好不容易...
进程同步模拟设计--生产者和消费者问题 进程调度同步异步
6. 使用信号量可以解决生产者-消费者问题,防止生产者和消费者线程同时操作缓冲区列表。 7. 互斥信号量用于阻止生产者线程和消费者线程同时操作缓冲区列表。 8. 信号量用于同步生产者线程和消费者线程的操作。
操作系统生产者和消费者问题操作系统生产者和消费者问题操作系统生产者和消费者问题操作系统生产者和消费者问题操作系统生产者和消费者问题
C语言编程模拟生产者和消费者问题 本文详细介绍了使用C语言模拟生产者和消费者问题的实现方法,包括实验目的、实验环境、实验步骤等。实验目的旨在模拟实现用同步机构避免发生进程执行时可能出现的与时间有关的错误...
(1)创建生产者和消费者线程 在Windows2000环境下,创建一个控制台进程,在此进程中创建n个线程来模拟生产者或者消费者。这些线程的信息由本程序定义的“测试用例文件”中予以指定。 该文件的格式和含义如下: 3 1 ...
linux下C++实现生产者和消费者问题,并及时输出缓存区的状态,方便理解。代码中有详细的注释,方便阅读。
操作系统经典实验,模拟生产者消费者问题,采用java语言编写,互斥同步
四川大学操作系统课程设计高分报告-第三次实验-生产者和消费者问题.doc 都是自己非常认真完成的,每一个要点都实现到位,程序全部跑通且符合要求。 保证每题均正确。 最后得到的分数也很好(均为最高分)
(1)掌握基本的同步互斥算法,理解生产者和消费者同步的问题模型。 (2)了解Windows 2000/XP中多线程的并发执行机制,线程间的同步和互斥。 (3)学习使用Windows2000/XP中基本的同步对象,掌握相应的API。 2、...
C语言编程模拟生产者和消费者问题 本文将详细介绍C语言编程模拟生产者和消费者问题的知识点,包括实验目的和要求、实验环境、实验步骤、PV操作同步机构、生产者和消费者问题、进程控制块PCB、处理器的模拟等。 ...
VC中实现的生产者和消费者问题的算法。此为转帖,算法讲的不错。
课程设计A:生产者和消费者问题课程设计A:生产者和消费者问题课程设计A:生产者和消费者问题
用java模拟生产者和消费者在缓冲区间的阻塞情况。
在生产者和消费者问题中,使用三个信号量full、empty、mutex来分别代表消费者的可用资源数、生产者的可用资源数、缓冲区是否可用。初值分别为full=0、empty=N、mutex=1。 知识点3:生产者和消费者问题的规则 生产者...
生产者和消费者问题的 C 语言编程模拟 生产者和消费者问题是操作系统中一种典型的同步问题,目的是为了解决多个进程之间的同步问题。在这个实验中,我们将使用 C 语言编程模拟生产者和消费者问题,使用 PV 操作同步...