3.9 生产者/消费者模式

生产者/消费者模式是五个同步问题的经典模型之一,从字面意义上理解,某个模块负责生产数据,而另一个模块负责处理这些数据,那么产生数据的模块,就称为生产者;而消费数据的模块就称为消费者。但是生产者/消费者模式还有一个重要的地方就是缓存区,你可以把它理解为一个古时候的媒婆,也就是现在的红娘,生产者把产生的数据放入缓存区,消费者从缓存区取得数据进行处理。

1. 生产者/消费者模式的优点

  1. 解耦

    生产者与消费者之间没有直接依赖,都依赖于缓存区。

  2. 并发

    正因为生产者与消费者没有直接耦合在一起,所以生产者与消费者是两个独立的并发主体,生产者把数据生产出来,放到缓存区,即可继续生产数据,消费者亦是如此。

  3. 支持任务不均

    有了缓冲区以后,如果数据产生与处理的速度不同,消费者未能及时处理的数据可以暂时存放在缓冲区。等生产者的制造速度放慢下拉,消费者再进行消化。

2. 生产者/消费者模型的原则

  1. 生产者与生产者之间是互斥关系。

  2. 生产者消费者之间是同步与互斥关系。

  3. 消费者与消费者之间是互斥关系。

3. 代码示例

我们知道,进程之间理论上是不可以直接通信和传递数据的。为了消除这个限制,我们可以借助一些第三方通道,比如消息队列。当然 multiprocessing 模块已经包装了底层机制,提供了 Queue、Pipes 等多种方式来交换数据,所以我们用Queue来演示,在父进程中创建两个子进程,一个往Queue里写数据,一个从Queue里读数据,一个简单的生产者消费者模型:

import time
import random
from multiprocessing import Process, Queue

def PUT(q):
    for value in range(1,5+1):
        print('存放 %d 到队列里.' % value)
        q.put(value)
        time.sleep(random.random())

def GET(q):
    while True:
        value = q.get(True)
        print('从队列之中取出了 %d.' % value)

if __name__ == '__main__':
    q = Queue()
    pw = Process(target=PUT, args=(q,))
    pr = Process(target=GET, args=(q,))
    pw.start()
    pr.start()
    pw.join()
    print('kill GET')
    pr.terminate()

运行结果如下:

存放 1 到队列里.
从队列之中取出了 1.
存放 2 到队列里.
从队列之中取出了 2.
存放 3 到队列里.
从队列之中取出了 3.
存放 4 到队列里.
从队列之中取出了 4.
存放 5 到队列里.
从队列之中取出了 5.
kill GET

这样,我们就完成了一个简单的生产者/消费者模型示例。

results matching ""

    No results matching ""