condition 锁
import threading
import random
import time
gmoney = 1000
gcondition = threading.Condition()
gtime = 0
class Productor(threading.Thread):
def run(self):
global gmoney
global gtime
while True:
money = random.randint(100, 1000)
gcondition.acquire()
if gtime >= 10:
gcondition.release()
break
gtime += 1
gmoney += money
print(f'生产者{threading.current_thread()},生产了{money}钱,现在一共有{gmoney}钱')
gcondition.notify_all()
gcondition.release()
time.sleep(0.5)
class Consumer(threading.Thread):
def run(self):
global gmoney
global gtime
while True:
money = random.randint(100, 1000)
gcondition.acquire()
while gmoney < money:
if gtime >= 10:
gcondition.release()
return
gcondition.wait()
gmoney -= money
print(f'消费者{threading.current_thread()},消费了{money}钱,余额为{gmoney}')
gcondition.release()
time.sleep(0.5)
def main():
for i in range(3):
t2 = Consumer(name=f'消费者{i}')
t2.start()
for i in range(3):
t1 = Productor(name=f'生产者{i}')
t1.start()
if __name__ == '__main__':
main()
当生产10次之后就停止生产
当取的钱比现有的钱多就会进行等待,再生产一次之后会唤醒所有等待的线程,唤醒的线程会排在后面。当执行到被唤醒的线程时,会在之前等待的地方继续往下执行。此时如果不用循环,在它继续往下执行时会出现问题,当它前面的线程消费了钱,到了它这里又不够了继续往下执行就会产生负数。所以需要循环判断需要取的钱和余额。
Lock锁
import threading
import random
import time
gmoney = 1000
glock = threading.Lock()
gtime = 0
class Productor(threading.Thread):
def run(self):
global gmoney
global gtime
while True:
money = random.randint(100, 1000)
glock.acquire()
if gtime >= 10:
glock.release()
break
gtime += 1
gmoney += money
print(f'生产者{threading.current_thread()},生产了{money}钱,现在一共有{gmoney}钱')
glock.release()
time.sleep(0.5)
class Consumer(threading.Thread):
def run(self):
global gmoney
global gtime
while True:
money = random.randint(100, 1000)
glock.acquire()
if gmoney >= money:
gmoney -= money
print(f'消费者{threading.current_thread()},消费了{money}钱,余额为{gmoney}钱')
else:
if gtime >= 10:
glock.release()
break
print(f'消费者{threading.current_thread()}需要{money}钱,余额为{gmoney},余额不足')
glock.release()
time.sleep(0.5)
def main():
for i in range(3):
t2 = Consumer(name=f'消费者{i}')
t2.start()
for i in range(3):
t1 = Productor(name=f'生产者{i}')
t1.start()
if __name__ == '__main__':
main()