python-44-初识队列

前言 

队列:先进先出,在多线程里面使用,队列内置有锁线程安全的数据结构,不用关心数据怎么放的,只要知道怎么用就可以,怎么插数据拿数据。

什么是生产者/消费者模型?为什么会出现生产者/消费者膨胀问题?
①比如生产者在生产,生产的货物积囤有限,那么可以一边卖给消费者,一边生产。
②但是这样子会导致任意一方可能出现 供过于求或供不应求,所以要平衡。

一、队列

队列的及格方法:

  • q.put():存,当队列满的时候阻塞等待队列有空位置
  • q.full():查看队列是否满了,不完全准确
  • q.get():取,当队列空的时候阻塞等待队列有数据
  • q.empty():判断队列是否为空
  • join():阻塞进程
  • task_done():检测任务完成

1、初识队列。

import time
from multiprocessing import Queue
q=Queue(3)              # 设置3个,没设置即为不上限
q.put(1)
q.put(2)
q.put(3)
print(q.full())         # 查看队列是否满了
print(q.get())          # 取走队列的对象
print(q.get())          # 取走队列的对象
print(q.get())          # 取走队列的对象
print(q.empty())        # 判断队列是否为空
# print(q.get_nowait())   # 如果为空,抛异常queue.Empty
while 1:
    try:q.get_nowait()
    except:
        print('队列为空!!!')
        time.sleep(1)

 2、队列在进程中使用。

# 2、队列在进程中使用
from multiprocessing import Process,Queue
def func(q):
    q.put('给我一个吻,可以不可以?')
def give(q):
    q.get()
if __name__ == '__main__':
    q=Queue()
    p=Process(target=func,args=(q,))
    p1=Process(target=give,args=(q,))
    p.start()
    p1.start()
    print(q.get())

二、生产者/消费者问题解决办法

1、Queue,第一种解决:生产者/消费者膨胀问题。

基本思路:①队列实现,消费者一直获取值,直到获取到None就意味着队列没有值。

但是有个不好之处,消费者不知道生产者的产量,直到取到None。

# 1、Queue,第一种解决:生产者/消费者膨胀问题。
import time
import random
from multiprocessing import Process,Queue
def consumer(q,name):
    while 1:
        mask = q.get()
        if mask is None:
            print('%s口罩空'%name)
            break
        print('%s使用了 %s' % (name,mask))
        time.sleep(random.randint(1,3))

def producer(name,mask,q):
    for i in range(1,5):
        time.sleep(random.randint(1,3))
        m = '%s生产了%s %s'%(name,mask,i)
        print(m)
        q.put(m)

if __name__  == '__main__':
    q = Queue()
    p1 = Process(target=producer,args=('大厂','N95口罩',q))
    p2 = Process(target=producer, args=('小厂','N90口罩', q))
    c1 = Process(target=consumer, args=(q,'A企业'))
    c2 = Process(target=consumer, args=(q,'B企业'))
    p1.start()
    p2.start()
    c1.start()
    c2.start()
    p1.join()
    p2.join()
    q.put(None)
    q.put(None)

2、JoinableQueue,第二种解决:生产者/消费者膨胀问题。

基本思路:
①消费者 中把所有的任务执行完;
②生产者 中的p.join()感知到消费者任务执行完就停止阻塞;
③生产者停止堵塞后意味着 生产者 的所有进程结束;
主进程中的p.join()结束
主进程中代码结束
守护进程(消费者的进程)结束

# 2、JoinableQueue,第二种解决:生产者/消费者膨胀问题。
import time
import random
from multiprocessing import Process,JoinableQueue
def consumer(q,name):
    while 1:
        mask = q.get()
        if mask is None:
            print('%s口罩空'%name)
            break
        print('%s使用了 %s' % (name,mask))
        time.sleep(random.randint(1,3))
        q.task_done()                      # 类似监控生产的数量,计数器每次-1

def producer(name,mask,q):
    for i in range(1,5):
        time.sleep(random.randint(1,3))
        m = '%s生产了%s %s'%(name,mask,i)
        print(m)
        q.put(m)
    q.join()                             # 堵塞,等到队列中的所有数据全部都被消费者执行完

if __name__  == '__main__':
    q = JoinableQueue()
    p1 = Process(target=producer,args=('大厂','N95口罩',q))
    p2 = Process(target=producer, args=('小厂','N90口罩', q))
    c1 = Process(target=consumer, args=(q,'A企业'))
    c2 = Process(target=consumer, args=(q,'B企业'))
    p1.start()
    p2.start()
    c1.daemon=True      # 设为守护进程,既是主进程的代码执行完后子进程自动结束
    c2.daemon=True      # 设为守护进程,既是主进程的代码执行完后子进程自动结束
    c1.start()
    c2.start()
    p1.join()
    p2.join()

欢迎来大家QQ交流群一起学习:482713805

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姚二龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值