六、 Condition版本的生产者和消费者模式
Lock版本的生产者与消费者模式可以正常的运行。但是存在一个不足,在消费者中,总是通过while True死循环并且上锁的方式去判断钱够不够。上锁是一个很耗费CPU资源的行为。因此这种方式不是最好的。
还有一种更好的方式便是使用threading.Condition来实现。
Threading.Condition可以在没有数据的时候处于阻塞等待状态。一旦有合适的数据了,还可以使用notify相关的函数来通知其他处于等待状态的线程。这样就可以不用做一些无用的上锁和解锁的操作。可以提高程序的性能。
首先对threading.Condition相关的函数做个介绍,threading.Condition类似threading.Lock,可以在修改全局数据的时候进行上锁,也可以在修改完毕后进行解锁。以下将一些常用的函数做个简单的介绍:
1.、acquire:上锁。
2、release:解锁。
3、wait:将当前线程处于等待状态,并且会释放锁。可以被其他线程使用notify和notify_all函数唤醒。被唤醒后会继续等待上锁,上锁后继续执行下面的代码。
4、notify:通知某个正在等待的线程,默认是第一个等待的线程。
5、notify_all:通知所有正在等待的线程。notify和notify_all不会释放锁。并且需要在release之前调用。
示例代码:
# import threading
# import random
# import time
#
# gMoney = 1000
# gCondition = threading.Condition()
# gTimes= 0
# gTotalTimes = 5
#
#
# class Producer(threading.Thread):
# def run(self):
# global gMoney
# global gCondition
# global gTimes
# while True:
# money = random.randint(100, 1000)
# gCondition.acquire()
# if gTimes >= gTotalTimes:
# gCondition.release()
# print('当前生产者总共生产了%s次' % gTimes)
# break
# gMoney += money
# print("%s当前存入%s元钱,剩余%s元钱" % (threading.current_thread(), money, gMoney))
# gTimes += 1
# time.sleep(0.5)
# gCondition.notify_all()
# gCondition.release()
#
#
# class Consumer(threading.Thread):
# def run(self) -> None:
# global gMoney
# global gCondition
# while True:
# money = random.randint(100, 500)
# gCondition.acquire()
# #这里要给个while循环判断,因为等轮到这个线程的时候,条件有可能又不满足了
# while gMoney < money:
# if gTimes >= gTotalTimes:
# gCondition.release()
# print("%s准备取%d元钱,剩余%s元钱,不足!" % (threading.current_thread(), money, gMoney))
# gCondition.wait()
# gMoney -= money
# print('%s当前取出%s元钱,剩余%s元钱' % (threading.current_thread(), money, gMoney))
# time.sleep(0.5)
# gCondition.release()
#
#
# def main():
# for x in range(5):
# Consumer(name="消费者线程%d" % x).start()
#
# for x in range(2):
# Producer(name="生产者线程%d" % x).start()
#
#
# if__name__ == '__main__':
# main()
import threading
import random
import time
gMoney= 0
gCondition= threading.Condition()
gTimes= 0
class Producer(threading.Thread):
def run(self):
global gMoney
global gTimes
while True:
gCondition.acquire()
if gTimes >= 10:
gCondition.release()
break
money = random.randint(0, 100)
gMoney += money
gTimes += 1
print("%s生产了%d元钱,剩余%d元钱" % (threading.current_thread().name, money, gMoney))
gCondition.notify_all()
gCondition.release()
time.sleep(1)
class Consumer(threading.Thread):
def run(self) -> None:
global gMoney
while True:
gCondition.acquire()
money = random.randint(0, 100)
while gMoney < money:
if gTimes >= 10:
print("%s想消费%d元钱,但是余额只有%d元钱,并且生产者已经不再生产了!" % (threading.current_thread().name, money, gMoney))
gCondition.release()
return
print("%s想消费%d元钱,但是余额只有%d元钱了,消费失败!" % (threading.current_thread().name, money, gMoney))
gCondition.wait()
gMoney -= money
print("%s消费了%d元钱,剩余%d元钱" % (threading.current_thread(). name, money, gMoney))
gCondition.release()
time.sleep(1)
def main():
for x in range(5):
th = Producer(name="生产者%d号" % x)
th.start()
for x in range(5):
th = Consumer(name="消费者%d号" % x)
th.start()
if__name__ == '__main__':
main()
上一篇文章 第五章 爬虫进阶(五) 2020-01-22 地址:
https://www.jianshu.com/p/5a48a27fa59e
下一篇文章 第五章 爬虫进阶(七) 2020-01-24 地址:
https://www.jianshu.com/p/c6a6eaf97547
以上资料内容来源网络,仅供学习交流,侵删请私信我,谢谢。