[操作系统]生产者/消费者问题

生产者/消费者问题也叫缓存绑定问题(bounded- buffer),是一个经典的、多进程同步问题。

单生产者和单消费者

仓库容量为一的情况

问题分析:

  • 仓库有空位时,生产者才能生产产品,并放入仓库中;
  • 仓库中存在产品时,消费者才能将产品从仓库中拿出来消费。

解决方法:

这是一个典型的同步问题,定义两个信号量:
- 信号量S1:(代表仓库中空位的数量)保证生产者不向满仓库中放入产品;
- 信号量S2:(代表仓库中产品的数量)保证消费者不从空仓库中取出产品。

伪代码

S1=1
S2=0
//P进程(生产者进程)
while(true){
    //生产一个产品
    P(S1)
    //把产品放入缓冲区
    V(S2)
}
//Q进程(消费者进程)
while(true){
    P(S2)
    //从缓冲区中取出一个产品
    V(S1)
    //消费该产品
}

仓库容量为N的情况

问题分析:

  • 仓库有空位时,生产者才能生产产品,并放入仓库中;
  • 仓库中存在产品时,消费者才能将产品从仓库中拿出来消费。

解决方法:

这是一个典型的同步问题,定义两个信号量:
- 信号量S1:(代表仓库中空位的数量)保证生产者不向满仓库中放入产品;
- 信号量S2:(代表仓库中产品的数量)保证消费者不从空仓库中取出产品。

伪代码

S1=N
S2=0
//P进程(生产者进程)
i=0
while(true){
    //生产一个产品
    P(S1)
    //把产品放入缓冲区Buffer[i]
    V(S2)
    i=(i+1)%N
}
//Q进程(消费者进程)
j=0
while(true){
    P(S2)
    //从缓冲区Buffer[j]中取出一个产品
    V(S1)
    //消费该产品
    i=(i+1)%N
}

仓库容量为无穷大的情况

信号量S1:(代表仓库中空位的数量无穷大)在任何时候都有空位,因此不需要S1。

伪代码

S2=0
//P进程(生产者进程)
i=0
while(true){
    //生产一个产品
    //把产品放入缓冲区Buffer[i]
    V(S2)
    i=(i+1)
}
//Q进程(消费者进程)
j=0
while(true){
    P(S2)
    //从缓冲区Buffer[j]中取出一个产品
    //消费该产品
    j=(j+1)
}

多生产者和多消费者

设有N个缓冲区、M个生产者、K个消费者。

问题分析:

  • 仓库有空位时,生产者才能生产产品,并放入仓库中;
  • 仓库中存在产品时,消费者才能将产品从仓库中拿出来消费;
  • 在同一时间,只能有一个生产者操作缓冲区,只能有一个消费者操作缓冲区。
    生产者和消费者所操作的缓冲区数组的下标不一致,因此可以并行操作。

解决方法:

这是一个典型的同步问题,定义两个信号量:
- 信号量S1:(代表仓库中空位的数量)保证生产者不向满仓库中放入产品;
- 信号量S2:(代表仓库中产品的数量)保证消费者不从空仓库中取出产品;
- 互斥量M1:保证生产者串行地访问缓冲区;
- 互斥量M2:保证消费者串行地访问缓冲区。

伪代码

S1=N
S2=0
//P进程(生产者进程)
i=0
while(true){
    //生产一个产品
    P(S1)
    P(M1)
    //把产品放入缓冲区Buffer[i]
    i=(i+1)%N
    V(M1)
    V(S2)
    i=(i+1)
}
//Q进程(消费者进程)
j=0
while(true){
    P(S2)
    P(M1)
    //从缓冲区Buffer[j]中取出一个产品
    j=(j+1)%N
    V(M1)
    V(S1)
    //消费该产品
}

猜你喜欢

转载自blog.csdn.net/zimengyu2020/article/details/79934887