zoukankan      html  css  js  c++  java
  • python中生产者消费者模式

     问题:

    1、为什么要使用生产者消费者模式?

    一直生产,一直消费,中间有阀值,避免供求关系不平衡,导致出现问题。

    #线程安全问题,要是线程同时来,听谁的

    #锁:一种数据结构 队列:先进线出 栈:先进后出

    2、生产者消费者模式作用?

    解耦:让程序各模块之间的关联性降到最低

    异步、并发

    平衡生产者和消费者之间的速度差异。

    •生产者消费者问题,也称有限缓冲问题,是一个多线程同步问题的经典案例

    •该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。

    •生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。

    •消费者也在缓冲区消耗这些数据。

    •该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据

    创建思路:

    创建一个共享区,共享区的容量为10(使用整型count变量模拟)

    •2个生产者,每个生产者消耗随机的时间单位生产1件商品并放入共享区(count自增1模拟),当共享区已满,生产者停止放入共享区,线程进入block阻塞状态,等待消费者线程唤醒。

    •5个消费者,每个消费者使用随机的时间单位每次从共享区获取1件商品(count自减1模拟),当共享区已空,消费者停止从共享区获取,线程进入block阻塞状态,等待生产者线程唤醒。

    实现方式:

    threading.Condition()

    import threading   #导入多线程模块
    import time        #导入时间模块
    import random      #导入随机模块
     
    count = 0 #使用共享区模拟变量
    condition = threading.Condition()   #创建条件对象
     
    #创建生产者线程类
    class Producer(threading.Thread):
        def __init__(self, threadName): #构造方法
            threading.Thread.__init__(self)
            self.threadName = threadName
            pass
        def run(self):
            global count   #引用全局变量
            while True:
                if condition.acquire(): #使用条件对象获取锁并锁定
                    if count >= 10:   # 判断共享变量是否已达到上限
                        print("共享区已满,生产者Producer线程进入阻塞Block状态,停止放入!")
                        condition.wait()  #当前线程进入阻塞状态
                        pass
                    else:
                        count += 1 #共享变量自增1
                        msg = time.ctime() + ' ' + self.threadName + '生产了1件商品放入共享区,共享区商品总数: ' + str(count)
                        print(msg)
                        condition.notify()  #唤醒其消费者线程
                        pass
                    condition.release()  #解除锁定
                    time.sleep(random.randrange(10)/5)  #随机休眠n秒
     
     
    class Customer(threading.Thread): #消费者线程类
        def __init__(self, threadName): #构造方法
            threading.Thread.__init__(self)
            self.threadName = threadName
            pass
        def run(self):
            global count   #引用全局变量
            while True:
                if condition.acquire(): #使用条件对象获取锁并锁定
                    if count < 1:   # 判断共享变量是否为空
                        print("共享区以空,消费者Customer线程进入阻塞Block状态,停止获取!")
                        condition.wait()  #当前线程进入阻塞状态
                        pass
                    else:
                        count -= 1 #共享变量自减1
                        msg = time.ctime() + ' ' + self.threadName + '消费了一件商品,共享区商品总数: ' + str(count)
                        print(msg)
                        condition.notify()  #唤醒其消费者线程
                        pass
                    condition.release()  #解除锁定
                    time.sleep(random.randrange(10))  #随机休眠n秒
                    pass
                pass
            pass
        pass
    if __name__ == '__main__':
        for i in range(2):
            p = Producer('[生产者-0' + str(i+1) + ']')
            p.start()
            pass
        for i in range(5):
            c = Customer('消费者-' + str(i+1) + ']')
            c.start()

    运行结果:

     
    Wed Aug 14 08:14:49 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 1
     
    Wed Aug 14 08:14:49 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 2
     
    Wed Aug 14 08:14:49 2019 消费者-1]消费了一件商品,共享区商品总数: 1
     
    Wed Aug 14 08:14:49 2019 消费者-2]消费了一件商品,共享区商品总数: 0
     
    共享区以空,消费者Customer线程进入阻塞Block状态,停止获取!
     
    共享区以空,消费者Customer线程进入阻塞Block状态,停止获取!
     
    共享区以空,消费者Customer线程进入阻塞Block状态,停止获取!
     
    共享区以空,消费者Customer线程进入阻塞Block状态,停止获取!
     
    Wed Aug 14 08:14:49 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 1
     
    Wed Aug 14 08:14:50 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 2
     
    Wed Aug 14 08:14:51 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 3
     
    Wed Aug 14 08:14:51 2019 消费者-3]消费了一件商品,共享区商品总数: 2
     
    Wed Aug 14 08:14:51 2019 消费者-3]消费了一件商品,共享区商品总数: 1
     
    Wed Aug 14 08:14:52 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 2
     
    Wed Aug 14 08:14:52 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 3
     
    Wed Aug 14 08:14:53 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 4
     
    Wed Aug 14 08:14:54 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 5
     
    Wed Aug 14 08:14:54 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 6
     
    Wed Aug 14 08:14:54 2019 消费者-2]消费了一件商品,共享区商品总数: 5
     
    Wed Aug 14 08:14:55 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 6
     
    Wed Aug 14 08:14:55 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 7
     
    Wed Aug 14 08:14:55 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 8
     
    Wed Aug 14 08:14:55 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 9
     
    Wed Aug 14 08:14:57 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 10
     
    共享区已满,生产者Producer线程进入阻塞Block状态,停止放入!
     
    共享区已满,生产者Producer线程进入阻塞Block状态,停止放入!
     
    Wed Aug 14 08:14:57 2019 消费者-5]消费了一件商品,共享区商品总数: 9
     
    Wed Aug 14 08:14:58 2019 消费者-1]消费了一件商品,共享区商品总数: 8
     
    Wed Aug 14 08:14:58 2019 消费者-1]消费了一件商品,共享区商品总数: 7
     
    Wed Aug 14 08:14:58 2019 消费者-2]消费了一件商品,共享区商品总数: 6
     
    Wed Aug 14 08:14:58 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 7
     
    Wed Aug 14 08:14:59 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 8
     
    Wed Aug 14 08:14:59 2019 消费者-4]消费了一件商品,共享区商品总数: 7
     
    Wed Aug 14 08:14:59 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 8
     
    Wed Aug 14 08:14:59 2019 消费者-3]消费了一件商品,共享区商品总数: 7
     
    Wed Aug 14 08:14:59 2019 消费者-3]消费了一件商品,共享区商品总数: 6
     
    Wed Aug 14 08:15:00 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 7
     
    Wed Aug 14 08:15:00 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 8
     
    Wed Aug 14 08:15:00 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 9

    Queue 队列实现

  • 相关阅读:
    一行命令搞定node.js 版本升级
    doesn't contain a valid partition table 解决方法
    debian kill 进程等命令
    FastDFS配置说明(中英文)
    FastDFS问题汇总
    FastDFS常见命令
    FastDFS安装配置手册
    windows 与Linux 互传文件
    FtpClient中文乱码问题解决
    windows 配置host
  • 原文地址:https://www.cnblogs.com/zhuyalong/p/13810193.html
Copyright © 2011-2022 走看看