Python学习 Day54 生产者与消费者模式 02

生产者与消费者模式

一、生产者消费者模式概述

生产者与消费者模式是多线程开发中常见的一种模式
1.生产者线程

  • 生产者线程用于“生产”数据

2.消费者线程

  • 消费者线程用于“消费”数据
    在这里插入图片描述
import threading
import random
import time
g_money = 0
#创建锁对象
lock = threading.Lock()
class Producer(threading.Thread):
    def run(self):
        global g_money
        for _ in range(10): #_只用来记录次数,所以无需使用迭代变量
            lock.acquire()
            money = random.randint(1000,10000)
            g_money+=money
            print(threading.current_thread().getName(),'挣了{}元,当前余额为:{}'.format(money,g_money))
            time.sleep(1)
            lock.release() #解锁
            
class Customer(threading.Thread):
    def run(self):
        global g_money
        for i in range(10):
            lock.acquire()
            money = random.randint(1000,10000)
            if money <= g_money:
                g_money = money
                print(threading.current_thread().getName(),'花了{}元,当前余额为:{}'.format(money,g_money))
            else:
                print(threading.current_thread().getName(),'想花{}元,但是余额不足,当前余额为:{}'.format(money,g_money))
            time.sleep(1)
            lock.release()
def start():
    for i in range(5):
        th = Producer(name='生产者{0}'.format(i))
        th.start()
    
    for i in range(5):
        cust = Customer(name='------------------消费者{}'.format(i))
        cust.start()

在这里插入图片描述


二、Condition版的生产者消费者模式

Condition版的生产者与消费者模式

函数 描述
acquire() 上锁
release() 解锁
wait() 将当前线程处于等待状态,并且会释放锁。可以被其他线程使用notify()和noti_all()函数唤醒。被唤醒后继续等待上锁,上锁后继续执行下面的代码
notify() 通知某个正等待的线程,默认是第一个等待的线程
notify_all() 通知所有正在等待的线程。notify()和notif_all()需要在release()之前调用

为什么要使用Condition版的生产者与消费者模式?

  • 因为当生产者生产次数使用完后,而当前的余额又不足以支撑消费者的使用,但程序仍然会输出“消费者n想使用资源,但资源不够”的冗余信息,实际上降低了程序运行的效率

如下所示
在这里插入图片描述
Condition版的生产者与消费者模式

  • 当生产者生产次数用完,消费者想消耗资源而资源不足时,即刻停止程序,节约程序运行时间
import threading
import random
import time
g_money = 0
#创建Condition对象
g_time = 0
lock = threading.Condition()
class Producer(threading.Thread):
    def run(self):
        global g_money
        global g_time
        for _ in range(10): #_只用来记录次数,所以无需使用迭代变量
            lock.acquire()
            money = random.randint(1000,10000)
            g_money+=money
            g_time+=1
            print(threading.current_thread().getName(),'挣了{}元,当前余额为:{}'.format(money,g_money))
            #time.sleep(1)
            lock.notify_all() #唤醒所有等待的线程
            lock.release() #解锁

class Customer(threading.Thread):
    def run(self):
        global g_money
        for i in range(10):
            lock.acquire() #上锁
            money = random.randint(1000,10000) #消费的金额
            while g_money < money:
                if g_time >= 50:
                    lock.release()
                    return
                print(threading.current_thread().getName(),'想花{}元,但是余额不足,当前余额为:{}'.format(money,g_money))
                lock.wait() #余额不足的情况下需要等待生产者生产
            g_money-=money #余额充足的情况下开始消费
            print(threading.current_thread().getName(),'--------------花了{}元,当前余额为:{}'.format(money,g_money))

            #time.sleep(1)
            lock.release()
def start():
    for i in range(5):
        th = Producer(name='生产者{0}'.format(i))
        th.start()

    for i in range(5):
        cust = Customer(name='------------------消费者{}'.format(i))
        cust.start()

if __name__ == '__main__':
    start()

在这里插入图片描述

Guess you like

Origin blog.csdn.net/ShengXIABai/article/details/116856430