python 为什么在条件变量中使用while控件而不是if控件来同步不同的线程?

afdcj2ne  于 12个月前  发布在  Python
关注(0)|答案(1)|浏览(129)

我有一个简单的生产者,消费者问题。当生产者线程向全局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变量。我是对的吗?或者我错过了什么?

368yc8dk

368yc8dk1#

使用while循环的原因在文档中有所暗示:
while循环检查应用程序的条件是必要的,因为wait()可以在任意长的时间后返回,并且提示notify()调用的条件可能不再为真。
如果你考虑你的代码有一个if-条件:

with condition:
    if money < 0:
        condition.wait()
    money -= 20

字符串
.有可能(至少就条件变量的实现而言),

  1. condition被锁定
  2. money小于0
    1.我们condition.wait();锁被解锁,其他地方发生了“一些事情”
    1.“something”通知所有在condition上等待的线程。
    1.另一个线程获取condition上的锁并执行,修改money,然后解锁condition
    1.我们的线程在获取锁后从.wait()返回
    1.当我们等待的条件在我们没有获得锁的时候变成了真,当我们没有获得锁的时候它也变成了假。我们被告知条件“改变”了。但是当我们去检查它的时候,它不再是真的了。
    虽然你的代码可能不会受到这个问题的影响,但通常情况下,良好的代码卫生//肌肉内存设计你的代码,使其不会受到上述问题的影响:当.wait()执行时,你的线程可能会得到通知,但当wait()返回时,你正在等待的条件不再为真
    while循环确保在锁被释放时,如果条件变为true和true,我们简单地再试一次。

相关问题