Appearance
2.19 经典模型:生产者消费者问题
一、生产者消费者模型
利用信号量解决生产者、消费者问题
生产者和消费者之间的联系
- 互斥
- 共享缓冲区(缓冲区作为一种临界资源)
- 同步
- 相互等待(有产品才能消费、有消费才能不断生产)
- 互斥
利用信号量解决生产者、消费者问题
定义哪些信号量?
如何对信号量进行初始化?
利用记录型信号量
假定在生产者和消费者之间的公用缓冲池中,具有n个缓冲区,这时可利用互斥信号量Mutex实现诸进程对缓冲池的互斥使用;利用信号量Empty和Full分别表示缓冲池中空缓冲区和满缓冲区的数量。又假定这些生产者和消费者相互等效,只要缓冲池未满,生产者便可将消息送入缓冲池;只要缓冲池未空,消费者便可从缓冲池中取走一个消息。对生产者—消费者问题可描述如下:
定义信号量
Semaphore Mutex=1; // 定义互斥信号量(临界资源信号量)
Semaphore Full=0,Empty=n; // 定义同步信号量
Product_Item Buffer[n]; // 定义产品缓冲区
int in=0; // 定义生产者初始指针
int out=0; //定义消费者初始指针
生产者进程
producer:
while(1)
{
...; // 生产者生产产品Pro_Item
P(Empty);
P(Mutex); // 可以直接P(Empty,Mutex)
Buffer[in]=Pro_Item;
in=(in++)%n;
V(Mutex);
V(Full); // 可以直接V(Mutex,Full)
}
消费者进程
Consumer:
while(1)
{
P(Full);
P(Mutex); // 可以直接P(Full,Mutex)
Item=Buffer[out];
out=(out++)%n;
V(Mutex);
V(Empty); // 可以直接V(Mutex,EMpty)
...; // 消费者消费过程
}
二、注意事项
每个程序中用于实现互斥的信号量Mutex的P操作和V操作必须成对地出现
对资源信号量Empty和Full的P操作和V操作同样需要成对出现,但它们分别处于不同的程序中
在每个程序中的多个P操作顺序不能颠倒。应先执行对资源信号量的P操作,然后再执行对互斥信号量的P操作,否则可能引起进程死锁。(可以直接使用AND信号量,即注释内容)