生产者与消费者模式
一、生产者消费者模式概述
生产者与消费者模式是多线程开发中常见的一种模式
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()