目录
经典进程同步问题
(1)生产者——消费者问题
单生产者——消费者问题
1.问题描述
系统中有一组生产者进程和一组消费者进程,生产者进程每次生产一个产品放入缓冲区;消费者进程每次从有界缓冲区中取出一个产品并使用。生产者和消费者共享一个初始为空、大小为n的缓冲区。
- 只有缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待。
- 只有缓冲区不空时,消费者才能从缓冲区中取出产品,否则必须等待。
- 缓冲区是临界资源,各进程必须互斥的访问
2.问题分析
由于缓冲区是临界资源必须互斥使用,因此需要设置一个互斥信号量mutex,缓冲区有两种状态:进程正在访问和没有进程正在访问,因此可以给mutex赋初值为1。
缓冲区中的大小是生产者和消费者都可以进行操作的,当缓冲区满时,生产者要等待消费者取走产品,按一定次序访问这属于同步关系;当缓冲区空时,消费者要等待生产者生产产品,按一定次序访问这属于同步关系,因此需要设置两个同步信号量,full和empty
Semaphore mutex = 1; //互斥信号量实现对缓冲区的互斥访问
Semaphore empty = n; //同步信号量,表示空闲缓冲区的数量,初值为有界缓冲区大小n
Semaphore full = 0; //同步信号量,表示产品数量,也是非空缓冲区数量,初值为0
3.伪代码逻辑实现
Producer(){
while (1)
{
生产一个产品;
P(empty); //消耗一个空闲缓冲区
P(mutex);
把产品放入缓冲区;
V(mutex);
V(full); //增加一个产品
}
}
Consumer(){
while (1)
{
生产一个产品;
P(full); //消耗一个产品
P(mutex);
把产品放入缓冲区;
V(mutex);
V(empty); //增加一个空闲缓冲区
}
}
由伪代码逻辑可以发现,实现两进程的同步关系,是在其中一个进程中执行P,另一个进程中执行V,(增加一个产品V(full) ,消耗一个产品P(full) )
不能交换两个P操作的先后顺序