我有一个简单的生产者,消费者问题。当生产者线程向全局money变量添加10$时,消费者线程将花钱。但有一个条件,即money不能小于0。下面给出的示例代码:
from threading import Thread, Condition
condition = Condition()
money = 0
def producer():
global money
for _ in range(1000000):
condition.acquire()
money += 10
condition.notify()
condition.release()
def consumer():
global money
for _ in range(500000):
condition.acquire()
if money < 0:
# while money < 0: why it's needed ?
condition.wait()
money -= 20
print("money in the bank after spend => ", money)
condition.release()
if __name__ == "__main__":
t1 = Thread(target=producer, args=())
t2 = Thread(target=consumer, args=())
t1.start()
t2.start()
t1.join()
t2.join()
字符串
我看到很多例子,他们正在使用while money < 20:而不是我的if控件,我在那里感到困惑。当线程等待条件.wait()时,它只是释放条件锁,当消费者消耗10$时,然后通知生产者线程,producer函数首先获取条件锁。所以在那里使用while循环没有意义。因为每次线程通知,第一步被通知的线程尝试获取锁,其余的代码继续正常工作。所以没有必要使用while循环来控制money变量的即时变化,如果程序按预期运行,它将控制money变量。我是对的吗?或者我错过了什么?
1条答案
按热度按时间368yc8dk1#
使用
while
循环的原因在文档中有所暗示:while循环检查应用程序的条件是必要的,因为wait()可以在任意长的时间后返回,并且提示notify()调用的条件可能不再为真。
如果你考虑你的代码有一个
if
-条件:字符串
.有可能(至少就条件变量的实现而言),
condition
被锁定money
小于0
1.我们
condition.wait()
;锁被解锁,其他地方发生了“一些事情”1.“something”通知所有在
condition
上等待的线程。1.另一个线程获取
condition
上的锁并执行,修改money
,然后解锁condition
1.我们的线程在获取锁后从
.wait()
返回1.当我们等待的条件在我们没有获得锁的时候变成了真,当我们没有获得锁的时候它也变成了假。我们被告知条件“改变”了。但是当我们去检查它的时候,它不再是真的了。
虽然你的代码可能不会受到这个问题的影响,但通常情况下,良好的代码卫生//肌肉内存设计你的代码,使其不会受到上述问题的影响:当
.wait()
执行时,你的线程可能会得到通知,但当wait()
返回时,你正在等待的条件不再为真。while
循环确保在锁被释放时,如果条件变为true和true,我们简单地再试一次。