logo资料库

编程模拟实现生产者-消费者进程.docx

第1页 / 共7页
第2页 / 共7页
第3页 / 共7页
第4页 / 共7页
第5页 / 共7页
第6页 / 共7页
第7页 / 共7页
资料共7页,全文预览结束
中 北 大 学 软 件 学 院 实 验 报 告 专 业: 软件工程 方 向: 智慧城市 课程名称: 操作系统 班 级: 15140Z01 学 号: 1514010739 姓 名: 杨亮 辅导教师: 2016 年 3 月 制 成 绩 :
实 验 时 间 2017 年 11 月 4 日 14 时 学 时 数 4 至 17 时 实 验 名 称 2 . 实 验 目 的 进程同步控制 (1)加强对进程概念的理解,尤其是对进程的同步与互斥机制的理解。 (2)分析进程竞争资源的现象,学习解决进程互斥与同步的方法。 3. 实 验 内 容 编程模拟实现生产者-消费者进程。 测试类 TestClient .Java //消费者线程 Consumer .Java //生产者线程 Producer .Java 4. 实 验 原 理 或 流 程 图 生产者-消费者问题描述的是:有一群生产者进程在生产产品,并将这些产品提供给消 费者进程去消费。为使生产者进程与消费者进程能够并发执行,在两者之间设置了一个具有 n 个缓冲区的缓冲池,生产者进程将它所生产的产品放入一个缓冲区中;消费者进程可以从 一个缓冲区中取走产品去消费。尽管所有的生产者和消费者进程都是以异步方式运行的,但 它们之间必须保持同步,即不允许消费者进程到一个空缓冲区去取产品;也不允许生产者进 程向一个已经装满产品的缓冲区中投放产品。 这是一个同步与互斥共存的问题。 生产者—消费者问题是一个同步问题。即生产者和消费者之间满足如下条件: (1) 消费者想接收数据时,有界缓冲区中至少有一个单元是满的。 (2) 生产者想发送数据时,有界缓冲区中至少有一个单元是空的。 故设置两个信号量: (1) empty:说明空缓冲区的数目,初值为有界缓冲区的大小 N。 (2) full:说明已用缓冲区的数目,初值为0。 由于有界缓冲区是临界资源,因此,各生产者进程和各消费者进程之间必须互斥执行。 故设置一个互斥信号量 mutex,其初值为1。
5. 实 验 过 程 或 源 代 码 //测试类 package com; public class TestClient { TestClient .Java public static void main(String[] args) { String lock = new String(""); // 创建对象锁 P p = new P(lock); C r = new C(lock); ThreadP pThread = new ThreadP(p); ThreadC cThread = new ThreadC(r); pThread.start(); cThread.start(); } } //缓冲池 class ValueObject { public static int size = 10; } //生产者线程 package com; Producer .Java import java.util.Random; public class Producer extends Thread{ private P p; public Producer(P p){ this.p = p; } public void run(){ //生产者不停的向缓冲池中存放数据 while(true){ try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace();
} p.setValue(); } } } class P { private String lock; public P(String lock){ this.lock = lock; } public void setValue(){ Random random = new Random(); try{ synchronized (lock) { //如果不为空,生产者处于等待状态 if(!(ValueObject.size == 0)){ 待这个池没有数据被消费者用,它用完之后,我就放新的数据 "); System.out.println("我是生产者,此时缓冲池中有数据,我正在等 try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } lock.wait(); }else{ ValueObject.size = random.nextInt(20); //随机产生 0 到 20 的数 存入缓冲池中 } lock.notify(); } }catch(InterruptedException e){ e.printStackTrace(); } } } //消费者线程 Consumer .Java package com; public class Consumer extends Thread{
private C c; public Consumer(C c){ this.c = c; } public void run(){ /** * 消费者不停的从缓冲池中取数据 */ while(true){ c.getValue(); try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } class C { private String lock; public C(String lock){ this.lock = lock; } public void getValue(){ try{ synchronized (lock) { //当没有值可供消费者使用时,使用消费者的线程处于等待状态 if(ValueObject.size==0){ System.out.println("我是消费者,我要产品:"); try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } lock.wait();
}else{ System.out.println("消费者获取到的值 是:"+ValueObject.size); ValueObject.size--; //消费者取值之后,将当前值减一 } lock.notify(); //唤醒生产者可以向缓冲池中存放数据了 }catch(InterruptedException e){ e.printStackTrace(); } } } } 6. 实 验 结 论 及 心 得
分享到:
收藏