Python的队列queue在多线程中的应用

import threading
import time
from queue import Queue


class Producer(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        count = 0
        while True:
            if queue.qsize() < 300:
                for i in range(300):
                    # count += 1
                    count = count + 1
                    msg = self.name + '生产产品' + str(count)
                    queue.put(msg)
                    print(msg)
            time.sleep(0.5)


class Consumer(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        while True:
            if queue.qsize() > 100:
                for i in range(3):
                    msg = self.name + '消费了' + queue.get()
                    print(msg)
            time.sleep(1)  # 即同一线程消费三个会休息1s


if __name__ == '__main__':
    queue = Queue()
    for i in range(100):
        queue.put('初始产品' + str(i))

    for i in range(2):
        p = Producer()  # 虽然有两个线程但是仍然是线程1写一次后线程2写,队列具有原子性,即要么不做,要么做完
        p.start()

    for i in range(5):
        c = Consumer()  # 创建5个消费者线程则线程名称会从thread-3开始,因为有两个生产者线程将1和2占用了
        c.start()

消费队列返回:

Thread-3消费了Thread-1生产产品2541
Thread-3消费了Thread-1生产产品2542
Thread-3消费了Thread-1生产产品2543
Thread-7消费了Thread-1生产产品2544
Thread-7消费了Thread-1生产产品2545
Thread-7消费了Thread-1生产产品2546
Thread-6消费了Thread-1生产产品2547
Thread-6消费了Thread-1生产产品2548
Thread-6消费了Thread-1生产产品2549
Thread-5消费了Thread-1生产产品2550
Thread-5消费了Thread-1生产产品2551
Thread-5消费了Thread-1生产产品2552
Thread-4消费了Thread-1生产产品2553
Thread-4消费了Thread-1生产产品2554
Thread-4消费了Thread-1生产产品2555


生产队列返回:

Thread-1生产产品2985
Thread-1生产产品2986
Thread-1生产产品2987
Thread-1生产产品2988
Thread-1生产产品2989
Thread-1生产产品2990
Thread-1生产产品2991
Thread-1生产产品2992
Thread-1生产产品2993
Thread-1生产产品2994
Thread-1生产产品2995
Thread-1生产产品2996
Thread-1生产产品2997
Thread-1生产产品2998
Thread-1生产产品2999
Thread-1生产产品3000


生产队列中,两个队列会轮流生成,保证队列在线程中的原子性

Queue的说明

  1. 对于Queue,在多线程通信之间扮演重要的角色
  2. 添加数据到队列中,使用put()方法
  3. 从队列中取数据,使用get()方法
  4. 判断队列中是否还有数据,使用qsize()方法

生产者消费者模式的说明

  • 为什么要使用生产者和消费者模式

在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。

  • 什么是生产者消费者模式

生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

这个阻塞队列就是用来给生产者和消费者解耦的。纵观大多数设计模式,都会找一个第三者出来进行解耦。

其实生产与消费模式中,对于消费者来说都是去获取数据,多一层解耦个人理解对消费者影响其实有限,主要是对生产者,比如消费者消费慢,那生产者是给消费者还是不给,是否需要暂停生产,等等都是问题,而有了第三方队列,生产者则无需关心消费者消费快慢的问题,只需安心生产,消费者消费慢了可以多加几个消费者,消费快了可以延时消费。就如同饭店的饭菜如果直接给到某个具体的消费者,消费者吃的慢,一个劲儿的上,势必消费不完,如果放到某个地儿让消费者自取或者邀请朋友一起去取,则能控制消费速度。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值