03生产者消费者模型

from multiprocessing import Process, Queue, JoinableQueue
import time, random, os

def producer(q):
    for i in range(10):
        time.sleep(random.randint(1,3))
        res = '包子{}'.format(i)
        q.put(res)
        print('{}生产了{}'.format(os.getpid(), res))

def consumer(q):
    while True:
        res = q.get()
        time.sleep(random.randint(1,3))
        print('{}吃了{}'.format(os.getpid(), res))

if __name__ == '__main__':
    q = Queue()
    # 生产者
    p1 = Process(target=producer, args=(q,))
    # 消费者
    c1 = Process(target=consumer, args=(q,))

    p1.start()
    c1.start()
    print('')

 上面程序的问题是不能正常结束,消费者不能结束,下面是改动后

def producer(q):
    for i in range(3):
        time.sleep(random.randint(1,3))
        res = '包子{}'.format(i)
        q.put(res)
        print('{}生产了{}'.format(os.getpid(), res))

def consumer(q):
    while True:
        res = q.get()
        if res is None:break
        time.sleep(random.randint(1,3))
        print('{}吃了{}'.format(os.getpid(), res))

if __name__ == '__main__':
    q = Queue()
    # 生产者
    p1 = Process(target=producer, args=(q,))
    # 消费者
    c1 = Process(target=consumer, args=(q,))

    p1.start()
    c1.start()

    p1.join()
    q.put(None)
    print('')
如果有多个生产者、消费者,那么做如下改动,这个做法很不好,以后用JoinableQueue
def producer(q):
    for i in range(3):
        time.sleep(random.randint(1,3))
        res = '包子{}'.format(i)
        q.put(res)
        print('{}生产了{}'.format(os.getpid(), res))

def consumer(q):
    while True:
        res = q.get()
        if res is None:break
        time.sleep(random.randint(1,3))
        print('{}吃了{}'.format(os.getpid(), res))

if __name__ == '__main__':
    q = Queue()
    # 生产者
    p1 = Process(target=producer, args=(q,))
    p2 = Process(target=producer, args=(q,))
    # 消费者
    c1 = Process(target=consumer, args=(q,))
    c2 = Process(target=consumer, args=(q,))
    c3 = Process(target=consumer, args=(q,))

    p1.start()
    p2.start()
    c1.start()
    c2.start()
    c3.start()

    p1.join()
    p2.join()
    q.put(None)#有几个消费者就要传递几个信号
    q.put(None)
    q.put(None)
    print('')
用JoinableQueue与守护进程应用来解决问题
JoinableQueue([maxsize]):这就像是一个Queue对象,但队列允许项目的使用者通知生成者项目已经被成功处理。
通知进程是使用共享的信号和条件变量来实现的。

#参数介绍:
maxsize是队列中允许最大项数,省略则无大小限制。
方法介绍:
JoinableQueue的实例p除了与Queue对象相同的方法之外还具有:
q.task_done():使用者使用此方法发出信号,表示q.get()的返回项目已经被处理。如果调用此方法的次数大于从队列中删除项目的数量,将引发ValueError异常
q.join():生产者调用此方法进行阻塞,直到队列中所有的项目均被处理。阻塞将持续到队列中的每个项目均调用q.task_done()方法为止
def producer(q):
    for i in range(3):
        time.sleep(random.randint(1,3))
        res = '包子{}'.format(i)
        q.put(res)
        print('{}生产了{}'.format(os.getpid(), res))

def consumer(q):
    while True:
        res = q.get()
        if res is None:break
        time.sleep(random.randint(1,3))
        print('{}吃了{}'.format(os.getpid(), res))
        q.task_done()

if __name__ == '__main__':
    q = JoinableQueue()
    # 生产者
    p1 = Process(target=producer, args=(q,))
    p2 = Process(target=producer, args=(q,))
    # 消费者
    c1 = Process(target=consumer, args=(q,))
    c2 = Process(target=consumer, args=(q,))
    c3 = Process(target=consumer, args=(q,))
    c1.daemon = True#设置为守护进程
    c2.daemon = True#设置为守护进程
    c3.daemon = True#设置为守护进程

    p1.start()
    p2.start()
    c1.start()
    c2.start()
    c3.start()

    p1.join()
    p2.join()
    q.join()#保证队列为空
    print('')##消费者已设置为守护进程,主进程结束后,子进程也会随之结束

 




posted @ 2021-03-01 10:03  cheng4632  阅读(73)  评论(0编辑  收藏  举报