操作系统生产者消费者缓冲池与区的问题.docx

上传人:b****8 文档编号:10481844 上传时间:2023-02-13 格式:DOCX 页数:21 大小:199.15KB
下载 相关 举报
操作系统生产者消费者缓冲池与区的问题.docx_第1页
第1页 / 共21页
操作系统生产者消费者缓冲池与区的问题.docx_第2页
第2页 / 共21页
操作系统生产者消费者缓冲池与区的问题.docx_第3页
第3页 / 共21页
操作系统生产者消费者缓冲池与区的问题.docx_第4页
第4页 / 共21页
操作系统生产者消费者缓冲池与区的问题.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

操作系统生产者消费者缓冲池与区的问题.docx

《操作系统生产者消费者缓冲池与区的问题.docx》由会员分享,可在线阅读,更多相关《操作系统生产者消费者缓冲池与区的问题.docx(21页珍藏版)》请在冰豆网上搜索。

操作系统生产者消费者缓冲池与区的问题.docx

操作系统生产者消费者缓冲池与区的问题

一个生产者一个消费者对应一个缓冲区;

源程序:

我用的是java语言。

importjava.lang.Math;

publicclassAProBuffCon//加互斥锁的缓冲区

{

privateintvalue;//共享变量

privatebooleanisEmpty=true;//value是否为空的信号量

publicsynchronizedvoidput(inti)//同步方法

{

while(!

isEmpty)//当value不空时,等待

try

{

this.wait();//使调用该方法的当前线程等待,即阻塞自己

}

catch(InterruptedExceptione){}

value=i;//当value空时,value获得值

System.out.println(Thread.currentThread().getName()+"Producerput:

"+value);

isEmpty=false;//设置value为不空状态

notifyAll();//唤醒其他所有等待线程

}

publicsynchronizedintget()//同步方法

{

while(isEmpty)//当value空时,等待

try

{

this.wait();

}

catch(InterruptedExceptione){}

isEmpty=true;//设置value为空状态,并返回值

notifyAll();//唤醒其他所有等待线程

returnvalue;

}

publicstaticvoidmain(Stringargs[])

{

AProBuffConbuffer=newAProBuffCon();

(newProducered(buffer)).start();//构造两个生产者线程和两个消费者线程

(newConsumered(buffer)).start();

}

}

classProduceredextendsThread//生产者

{

privateAProBuffConbuffer;

publicProducered(AProBuffConbuffer)

{

this.buffer=buffer;

}

publicvoidrun()

{

//for(inti=1;i<=10;i++)

//{

intj=(int)(Math.random()*10);

buffer.put(j);

//}

}

}

classConsumeredextendsThread//消费者

{

privateAProBuffConbuffer;

publicConsumered(AProBuffConbuffer)

{

this.buffer=buffer;

}

publicvoidrun()

{

//for(inti=1;i<=10;i++)//消费者从缓冲区中取数

System.out.println("\t\t\t\t"+Thread.currentThread().getName()+"Consumerget:

"+buffer.get());

}

}

说明:

都是先生产在消费。

多个生产者多个消费者对应一个缓冲区

源程序:

importjava.lang.Math;

publicclassAProBuffCon//加互斥锁的缓冲区

{

privateintvalue;//共享变量

privatebooleanisEmpty=true;//value是否为空的信号量

publicsynchronizedvoidput(inti)//同步方法,synchronized保证一段时间内只有一个对象访问这段程序

{

while(!

isEmpty)//当value不空时,等待

try

{

this.wait();//使调用该方法的当前线程等待,即阻塞自己

}

catch(InterruptedExceptione){}

value=i;//当value空时,value获得值

System.out.println(Thread.currentThread().getName()+"生产了:

"+value);

isEmpty=false;//设置value为不空状态

notifyAll();//唤醒其他所有等待线程

}

publicsynchronizedvoidget()//同步方法,这个成为了事实上的消费者,因为如果在外部消费,信号量不好传递

{

while(isEmpty)//当value空时,等待

try

{

this.wait();

}

catch(InterruptedExceptione){}

isEmpty=true;//设置value为空状态,并返回值

System.out.println("\t\t\t\t"+Thread.currentThread().getName()+"消费了"+value);

notifyAll();//唤醒其他所有等待线程

}

publicstaticvoidmain(Stringargs[])

{

AProBuffConbuffer=newAProBuffCon();

(newProducered(buffer)).start();

(newConsumered(buffer)).start();

(newProducered(buffer)).start();

(newConsumered(buffer)).start();

(newProducered(buffer)).start();

(newConsumered(buffer)).start();

(newProducered(buffer)).start();

(newConsumered(buffer)).start();

}

}

classProduceredextendsThread//生产者

{

privateAProBuffConbuffer;

publicProducered(AProBuffConbuffer)

{

this.buffer=buffer;

}

publicvoidrun()

{

intj=(int)(Math.random()*10);

buffer.put(j);

}

}

classConsumeredextendsThread//消费者

{

privateAProBuffConbuffer;

publicConsumered(AProBuffConbuffer)

{

this.buffer=buffer;

}

publicvoidrun()

{

buffer.get();

}

}

 

一个消费者一个生产者一个缓冲池

源程序及注释

importjava.lang.Math;

publicclassAProBuffCon//加互斥锁的缓冲区

{

privateintvalue[]=newint[10];//共享缓冲池

privateintin=0;//设置开关锁in标志向缓冲池生产数据,out标志消费缓冲池的数据

privateintout=0;

publicsynchronizedvoidput(inti)//同步方法,实际上向缓冲池生产数据,synchronized保证一段时间内只有一个对象访问这段程序

{

while((in+1)%10==out)//当缓冲池满时,等待

try

{

this.wait();//使调用该方法的当前线程等待,即阻塞自己

}

catch(InterruptedExceptione){}//trycatch语句,没什么意义

value[in]=i;//当缓冲池不满时,可以生产数据

System.out.println(Thread.currentThread().getName()+"在"+in+"号缓冲区"+"生产了:

"+value[in]);

in=(in+1)%10;//生产好数据后,in向后移动一位

notifyAll();//唤醒其他所有等待线程

}

publicsynchronizedvoidget()//同步方法,这个成为了事实上的消费者,因为如果在外部消费,信号量不好传递

{

while(in==out)//缓冲池为空时,等待

try

{

this.wait();

}

catch(InterruptedExceptione){}

System.out.println("\t\t\t\t"+Thread.currentThread().getName()+"消费了"+out+"号缓冲区数据:

"+value[out]);

out=(out+1)%10;//消费完数据,out后移一位

notifyAll();//唤醒其他所有等待线程

}

publicstaticvoidmain(Stringargs[])//主方法,产生一个消费者,一个生产者

{

AProBuffConbuffer=newAProBuffCon();

(newProducered(buffer)).start();//start()方法标志线程活过来了

(newConsumered(buffer)).start();

}

}

classProduceredextendsThread//名义上的生产者线程

{

privateAProBuffConbuffer;

publicProducered(AProBuffConbuffer)

{

this.buffer=buffer;

}

publicvoidrun()

{

for(inti=1;i<=20;i++)

{

intj=(int)(Math.random()*10);

buffer.put(j);

}

}

}

classConsumeredextendsThread//消费者

{

privateAProBuffConbuffer;

publicConsumered(AProBuffConbuffer)

{

this.buffer=buffer;

}

publicvoidrun()

{

for(inti=1;i<=20;i++)

buffer.get();

}

}

多个生产者多个消费者一个缓冲池

源程序:

importjava.lang.Math;

publicclassAProBuffCon//加互斥锁的缓冲区

{

privateintvalue[]=newint[10];//共享缓冲池

privateintin=0;//设置开关锁in标志向缓冲池生产数据,out标志消费缓冲池的数据

privateintout=0;

publicsynchronizedvoidput(inti)//同步方法,实际上向缓冲池生产数据,synchronized保证一段时间内只有一个对

象访问这段程序

{

while((in+1)%10==out)//当缓冲池满时,等待

try

{

this.wait();//使调用该方法的当前线程等待,即阻塞自己

}

catch(InterruptedExceptione){}//trycatch语句,没什么意义

value[in]=i;//当缓冲池不满时,可以生产数据

System.out.println(Thread.currentThread().getName()+"在"+in+"号缓冲区"+"生产了:

"+value[in]);

in=(in+1)%10;//生产好数据后,in向后移动一位

notifyAll();//唤醒其他所有等待线程

}

publicsynchronizedvoidget()//同步方法,这个成为了事实上的消费者,因为如果在外部消费,信号量不好传递

{

while(in==out)//缓冲池为空时,等待

try

{

this.wait();

}

catch(InterruptedExceptione){}

System.out.println("\t\t\t\t"+Thread.currentThread().getName()+"消费了"+out+"号缓冲区数据:

"+value[out]);

out=(out+1)%10;//消费完数据,out后移一位

notifyAll();//唤醒其他所有等待线程

}

publicstaticvoidmain(Stringargs[])//主方法,产生一个消费者,一个生产者

{

AProBuffConbuffer=newAProBuffCon();

(newProducered(buffer)).start();//start()方法标志线程活过来了

(newConsumered(buffer)).start();

(newProducered(buffer)).start();//start()方法标志线程活过来了

(newConsumered(buffer)).start();

(newProducered(buffer)).start();//start()方法标志线程活过来了

(newConsumered(buffer)).start();

}

}

classProduceredextendsThread//名义上的生产者线程

{

privateAProBuffConbuffer;

publicProducered(AProBuffConbuffer)

{

this.buffer=buffer;

}

publicvoidrun()

{

for(inti=1;i<=11;i++)

{

intj=(int)(Math.random()*10);

buffer.put(j);

}

}

}

classConsumeredextendsThread//消费者

{

privateAProBuffConbuffer;

publicConsumered(AProBuffConbuffer)

{

this.buffer=buffer;

}

publicvoidrun()

{

for(inti=1;i<=11;i++)

buffer.get();

}

}

为什么wait()和signal()一定得是原语?

wait()与signal()一定是原语,不能分开分析:

假设有下面一个关系:

S1

aa

S2S3

前提:

我们把S1当成是生产者,S2和S3为竞争的消费者,正常情况下,他们两个只能有一个来对S1生产的数据进行消费

当把wait()和signal()当做原语时程序可以写为:

Vara:

semaphore=0;

Begin

Parbegin

1.BeginS1;signal(a);end;

2.Beginwait(a);S2;end;

3.Beginwait(a);S3;end;

Parend

End

当把wait()和signal()分开来写时:

Vara:

semaphore=0;

Begin

Parbegin

1.BeginS1;a=a+1;end;

2.Beginwhile(a<=0)no-op;

A

a=a-1;

S2;end;

3.Beginwhile(a<=0)no-op;

B

a=a-1;

S3;end;

Parend

End

当是原语时,到底是哪个进程在执行,这个只有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