题目:
假定在生产者和消费者之间的公用缓冲池中具有n个缓冲区,消费者不能同时取一个缓冲区的产品,生产者不能同时向同一个缓冲区放入产品。只有缓冲区中有产品时,消费者才可以取产品,只有缓冲区有空时,生产者才可以放入产品。消费者与生产者也不能同时对同一个缓冲区进行操作。
代码:
信号量的设置:
名称 初值 含义
empty n 缓冲池中的空闲缓冲区个数
produce 0 缓冲池中产品的个数
mutex 1 同时对缓冲区的操作互斥控制
void producer(){
while(1){
wait(empty); //申请空位
wait(mutex);
//放入产品操作
signal(mutex);
signal(produce); //放置产品
}
}
void consumer(){
while(1){
wait(produce); //申请产品
wait(mutex);
//取出产品操作
signal(mutex);
signal(empty); //释放空位
}
}
int main(){
consumer.start();
producer.start();
}
分析:
问题相当简单,需要互斥的操作有两个:
①.放入产品操作,要满足:放时不能取,无时不能取
②.取出产品操作,要满足:拿时不能放,满时不能放
放时不能取和拿时不能放通过两个进程对同一个信号量mutex进行申请即可实现
无时不能取则让取方(消费者)对produce信号量进行申请,无则阻塞
满时不能放则让放方(生产者)对empty信号量进行申请,无时阻塞
更进一步的
在此问题上增加要求:消费者要一口气拿10个产品才退出,在此期间其他消费者不能拿取
那么,分析一下,只需要将拿取一个产品的操作当做一个整体,对这个整体操作再进行互斥控制,在拿满十次之前不让其他进程进入拿取操作即可.
消费者代码如下:
新增信号量:
keep 1 同时可进行取操作的消费者个数
void consumer(){
while(1){
wait(keep)
for(int i=0;i<10;i++)
{
wait(produce); //申请产品
wait(mutex);
//取出产品操作
signal(mutex);
signal(empty); //释放空位
}
signal(keep)
}
}
这样,当其他消费者试图取操作时,都会对keep信号量进行询问,若有人没取完10个,则会被阻塞在这里,等待signal(keep)的时候被唤醒.