1、操作系统生产者消费者缓冲池与区的问题一个生产者一个消费者对应一个缓冲区;源程序:我用的是java语言。import java.lang.Math;public class AProBuffCon /加互斥锁的缓冲区 private int value; /共享变量 private boolean isEmpty=true; /value是否为空的信号量 public synchronized void put(int i) /同步方法 while (!isEmpty) /当value不空时,等待 try this.wait(); /使调用该方法的当前线程等待,即阻塞自己 catch(Inter
2、ruptedException e) value = i; /当value空时,value获得值 System.out.println(Thread.currentThread().getName()+ Producer put : +value); isEmpty = false; /设置value为不空状态 notifyAll(); /唤醒其他所有等待线程 public synchronized int get() /同步方法 while (isEmpty) /当value空时,等待 try this.wait(); catch(InterruptedException e) isEmpt
3、y = true; /设置value为空状态,并返回值 notifyAll(); /唤醒其他所有等待线程 return value; public static void main (String args) AProBuffCon buffer = new AProBuffCon(); (new Producered(buffer).start(); /构造两个生产者线程和两个消费者线程 (new Consumered(buffer).start(); class Producered extends Thread /生产者 private AProBuffCon buffer; publi
4、c Producered(AProBuffCon buffer) this.buffer = buffer; public void run( ) / for (int i=1; i=10; i+) / int j=(int)(Math.random()*10); buffer.put(j); / class Consumered extends Thread /消费者 private AProBuffCon buffer; public Consumered(AProBuffCon buffer) this.buffer = buffer ; public void run() / for
5、(int i=1; i=10; i+) /消费者从缓冲区中取数 System.out.println(tttt+Thread.currentThread().getName()+ Consumer get : +buffer.get(); 说明: 都是先生产在消费。多个生产者多个消费者对应一个缓冲区源程序:import java.lang.Math;public class AProBuffCon /加互斥锁的缓冲区 private int value; /共享变量 private boolean isEmpty=true; /value是否为空的信号量 public synchronized
6、 void put(int i) /同步方法,synchronized保证一段时间内只有一个对象访问这段程序 while (!isEmpty) /当value不空时,等待 try this.wait(); /使调用该方法的当前线程等待,即阻塞自己 catch(InterruptedException e) value = i; /当value空时,value获得值 System.out.println(Thread.currentThread().getName()+ 生产了 : +value); isEmpty = false; /设置value为不空状态 notifyAll(); /唤醒其
7、他所有等待线程 public synchronized void get() /同步方法,这个成为了事实上的消费者,因为如果在外部消费,信号量不好传递 while (isEmpty) /当value空时,等待 try this.wait(); catch(InterruptedException e) isEmpty = true; /设置value为空状态,并返回值 System.out.println(tttt+Thread.currentThread().getName()+消费了 +value); notifyAll(); /唤醒其他所有等待线程 public static void
8、main (String args) AProBuffCon buffer = new AProBuffCon(); (new Producered(buffer).start(); (new Consumered(buffer).start(); (new Producered(buffer).start(); (new Consumered(buffer).start(); (new Producered(buffer).start(); (new Consumered(buffer).start(); (new Producered(buffer).start(); (new Consu
9、mered(buffer).start(); class Producered extends Thread /生产者 private AProBuffCon buffer; public Producered(AProBuffCon buffer) this.buffer = buffer; public void run( ) int j=(int)(Math.random()*10); buffer.put(j); class Consumered extends Thread /消费者 private AProBuffCon buffer; public Consumered(APro
10、BuffCon buffer) this.buffer = buffer ; public void run() buffer.get(); 一个消费者一个生产者一个缓冲池源程序及注释import java.lang.Math;public class AProBuffCon /加互斥锁的缓冲区 private int value=new int10; /共享缓冲池 private int in=0; /设置开关锁in标志向缓冲池生产数据,out标志消费缓冲池的数据 private int out=0; public synchronized void put(int i) /同步方法,实际上
11、向缓冲池生产数据,synchronized保证一段时间内只有一个对象访问这段程序 while (in+1)%10=out) /当缓冲池满时,等待 try this.wait(); /使调用该方法的当前线程等待,即阻塞自己 catch(InterruptedException e) /try catch语句,没什么意义 valuein = i; /当缓冲池不满时,可以生产数据 System.out.println(Thread.currentThread().getName()+在+in+号缓冲区+生产了 : +valuein); in=(in+1)%10; /生产好数据后,in向后移动一位 n
12、otifyAll(); /唤醒其他所有等待线程 public synchronized void get() /同步方法,这个成为了事实上的消费者,因为如果在外部消费,信号量不好传递 while (in=out) /缓冲池为空时,等待 try this.wait(); catch(InterruptedException e) System.out.println(tttt+Thread.currentThread().getName()+消费了+out+号缓冲区数据:+valueout); out=(out+1)%10; /消费完数据,out后移一位 notifyAll(); /唤醒其他所有
13、等待线程 public static void main (String args) /主方法,产生一个消费者,一个生产者 AProBuffCon buffer = new AProBuffCon(); (new Producered(buffer).start(); /start()方法标志线程活过来了 (new Consumered(buffer).start(); class Producered extends Thread /名义上的生产者线程 private AProBuffCon buffer; public Producered(AProBuffCon buffer) this
14、.buffer = buffer; public void run( ) for(int i=1;i=20;i+) int j=(int)(Math.random()*10); buffer.put(j); class Consumered extends Thread /消费者 private AProBuffCon buffer; public Consumered(AProBuffCon buffer) this.buffer = buffer ; public void run() for(int i=1;i=20;i+) buffer.get(); 多个生产者多个消费者一个缓冲池源程
15、序:import java.lang.Math;public class AProBuffCon /加互斥锁的缓冲区 private int value=new int10; /共享缓冲池 private int in=0; /设置开关锁in标志向缓冲池生产数据,out标志消费缓冲池的数据 private int out=0; public synchronized void put(int i) /同步方法,实际上向缓冲池生产数据,synchronized保证一段时间内只有一个对象访问这段程序 while (in+1)%10=out) /当缓冲池满时,等待 try this.wait();
16、/使调用该方法的当前线程等待,即阻塞自己 catch(InterruptedException e) /try catch语句,没什么意义 valuein = i; /当缓冲池不满时,可以生产数据 System.out.println(Thread.currentThread().getName()+在+in+号缓冲区+生产了 : +valuein); in=(in+1)%10; /生产好数据后,in向后移动一位 notifyAll(); /唤醒其他所有等待线程 public synchronized void get() /同步方法,这个成为了事实上的消费者,因为如果在外部消费,信号量不好传
17、递 while (in=out) /缓冲池为空时,等待 try this.wait(); catch(InterruptedException e) System.out.println(tttt+Thread.currentThread().getName()+消费了+out+号缓冲区数据:+valueout); out=(out+1)%10; /消费完数据,out后移一位 notifyAll(); /唤醒其他所有等待线程 public static void main (String args) /主方法,产生一个消费者,一个生产者 AProBuffCon buffer = new APr
18、oBuffCon(); (new Producered(buffer).start(); /start()方法标志线程活过来了 (new Consumered(buffer).start(); (new Producered(buffer).start(); /start()方法标志线程活过来了 (new Consumered(buffer).start(); (new Producered(buffer).start(); /start()方法标志线程活过来了 (new Consumered(buffer).start(); class Producered extends Thread /
19、名义上的生产者线程 private AProBuffCon buffer; public Producered(AProBuffCon buffer) this.buffer = buffer; public void run( ) for(int i=1;i=11;i+) int j=(int)(Math.random()*10); buffer.put(j); class Consumered extends Thread /消费者 private AProBuffCon buffer; public Consumered(AProBuffCon buffer) this.buffer =
20、 buffer ; public void run() for(int i=1;i=11;i+) buffer.get(); 为什么wait()和signal()一定得是原语?wait()与signal()一定是原语,不能分开分析:假设有下面一个关系: S1 a a S2 S3前提:我们把S1当成是生产者,S2和S3为竞争的消费者,正常情况下,他们两个只能有一个来对S1生产的数据进行消费 当把wait()和signal()当做原语时程序可以写为:Var a:semaphore=0;Begin Parbegin 1.Begin S1;signal(a);end;2.Begin wait(a);S
21、2;end;3.Begin wait(a);S3;end; ParendEnd 当把wait()和signal()分开来写时:Var a:semaphore=0;Begin Parbegin 1.Begin S1;a=a+1;end;2.Begin while(a=0) no-op; A a=a-1; S2;end;3.Begin while(a=0) no-op; B a=a-1; S3;end; ParendEnd 当是原语时,到底是哪个进程在执行,这个只有CPU知道,但是,我们可以确定,进程2 或3要运行,必须等进程1生产完之后产生信号量a;而且,这样可以确定,2进程和3进程只有一个能对数据进行消费,因为一旦原语不可分,一旦进入之后,就进行a-1操作,a=0就锁住了;当它们不是原语时,我们假设:a此时已经就是1了。当a进入进程2时,通过了所谓的身份验证即就是把while(a=0)这一步已经过去,到达A这一步,注意此时a=1,因为不是原语,可以跳出,CPU调用线程3,也通过了验证,然后到达B并且继续向下执行,直到进程3的消费结束,此时,CPU回到A的断点,继续执行,接着就会发生错误,因为已经没有可供消费的数据,产生错误,当然例子还有很多,我们把时间也给其他科目花一些吧,举这样。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1