生产者/消费者模式

生产者/消费者模式

生产者:产生数据的模块
消费者:处理数据的模块
两者通过内存缓冲区进行通信

python实现

生产者生产数据过快,消费者处理数据太慢?
	可以设置一个容器(队列)存放生产数据,用容器的大小限制生产速度,容器满了就不在生产
生产者生产数据过慢,消费者处理数据过快?
	多增加几个生产源
如何判断生产者生成数据完毕?
	a.判断队列是否为空,判断生成代码是否执行完毕
			但是q.empty不适用于多进程护环境
	b.队列现在为空,可能生产者还未来得及生产,不一定生产者代码执行完毕
		所以不能以队列是否为空判断生产者执行完毕
		在生产者结束后再次向队列添加一个标记数据,消费者获取到标记数据就关闭进程
		但是在多进程的多个消费模式下,获取到标记数据的进程会关闭,未获取到标记数据的会继续阻塞
		所以有多少个消费者就添加多少个标记数据
import time
import random
from multiprocessing import Queue,Process
def consumer(name,q):
    while True:
        s = q.get()
        if( s== 1):
            break
        time.sleep(random.randint(1,3))
        print('%s消费了%s'%(name,s))
                 
def producer(name,food,q):
    for i in range(10):
        s = '%s产生第%d个%s'%(name,i,food)
        print(s)
        q.put(s)
        time.sleep(random.randint(1,3))
                   
if __name__ == '__main__':
    q = Queue(20)#新建队列,容量为20——数据缓冲区
    p1 = Process(target = producer,args = ('主机1','数据1',q))
    p1.start()#启动生产者p1进程
    p2 = Process(target = producer,args = ('主机2','数据2',q))
    p2.start()#启动生产者p2进程
    c1 = Process(target = consumer,args = ('主机3',q))
    c1.start()#启动消费者c1进程
    c2 = Process(target = consumer,args = ('主机4',q))
    c2.start()#启动消费者c2进程
    p1.join()#感知生成者p1进程的结束
    p2.join()#感知生成者p2进程的结束
    q.put(1)#标记数据
    q.put(1)#标记数据

改进版

from multiprocessing import JoinableQueue
JoinableQueue模块比Queue模块多了两个方法,
在q.get数据后要提交一个回执q.task_done(),标记值-1,操作成功
队列每添加q.put()一个数据就自动增加一个标记值
q.join() 生产者代码执行结束后,阻塞当前代码直到消费者将数据全部处理完毕
import time
import random
from multiprocessing import JoinableQueue,Process
def consumer(name,q):
    while True:
        s = q.get()
        time.sleep(random.randint(1,3))
        print('%s消费了%s'%(name,s))
        q.task_done()    
          
def producer(name,food,q):
    for i in range(10):
        s = '%s生产了第%d个%s'%(name,i,food)
        print(s)
        q.put(s)
        time.sleep(random.randint(1,3))
        
    q.join() #阻塞,直到队列中所有数据全被处理完毕(消费者消费完毕)
    
if __name__ == '__main__':
    q = JoinableQueue(20)
    p1 = Process(target = producer,args = ('食堂阿姨','包子',q))
    p1.start()
    p2 = Process(target = producer,args = ('食堂大妈','馒头',q))
    p2.start()
    c1 = Process(target = consumer,args = ('学生1',q))
    c2 = Process(target = consumer,args = ('学生2',q))
    c1.daemon = True #将消费者设为守护进程——等待主进程代码执行完毕
    c2.daemon = True #将消费者设为守护进程——等待主进程代码执行完毕
    c1.start()  #启动消费者进程
    c2.start() #启动消费者进程
    p1.join() #感知生产者进程的结束——阻塞当前代码直到生产者生成完毕
    p2.join() #感知生产者进程的结束
#执行流程
#所有生产者代码执行结束后,队列.join()阻塞生产者,等待消费者处理完 
#消费者处理完数据,阻塞消失,生产者结束
#生产者结束,生产者进程.join()结束,主进程的代码执行完毕,守护线程(消费者结束)结束,然后主进程真正的结束
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值