python的线程模块中condition.notify()的意义是什么?

时间:2017-09-20 18:16:39

标签: python multithreading thread-safety python-multithreading producer-consumer

所以我在线程模块中使用了python的条件:

from threading import Thread, Condition
condition = Condition()

我有一个Producer类(Thread的子类),它基本上在for循环中将项添加到队列,直到队列已满(即达到定义的最大长度)和在for循环中的Consumer类弹出项目,除非队列是空的。在Producer中,如果队列已满,我们有一个 condition.wait()语句,类似于使用者类,如果队列为空,我们有一个condition.wait() 声明。如果这些条件都不满足(队列既不满也不空)每个类都做它的事情(将一个项添加到队列或弹出一个项,分别为Producer或Consumer)然后在释放条件之前( condition.release) ()),我们有一个 condition.notify()语句。我从文档中读到notify()唤醒其中一个等待的线程。

我现在的问题有两个方面:

  1. 究竟是什么"醒来"一个线程的意思?
  2. 当我从两个类中删除 notify()语句时,我的程序运行就好了for循环的几次迭代(即生产者推送项目和消费者弹出项目),然后在某些时候生产者不停地将项目推送到队列而没有消费者运行,队列变满了,但是消费者再也没有运行,程序只是暂停。 notify()对于此程序的性能至关重要。
  3. 非常感谢您的帮助:)

2 个答案:

答案 0 :(得分:0)

1)它表示等待锁定释放的线程可以继续执行。

2)Condition.notify(n)从内部队列中占用多达n个线程,并在它们等待的锁上调用release-从而将它们唤醒。如果内部队列为空,则没有人可以唤醒,并且notify调用无效。这就是为什么从一开始就删除notify无效,但是一旦消费者线程调用wait,就没有人唤醒他们,他们一直在等待。

答案 1 :(得分:0)

TL; DR

  1. 在这里醒来被视为唤醒生产者或消费者睡眠, AND 并通知他们一旦共享PPE,他们就可以恢复工作(基本锁定) )

  2. 消费者看到队列何时变空,然后进入睡眠状态,等待生产者将队列添加到队列中后将其唤醒。

    但是您已经剥夺了生产者唤醒消费者的能力。

    生产者看到队列何时装满,然后进入睡眠状态,等待消费者从队列中取出时将其唤醒。

    但是您已经剥夺了消费者唤醒生产者的能力。

    现在他们都睡着了。


适当的讨论

了解Condition.notify()的重要性的关键在于意识到,当您wait()处于某种条件下时,您正在等待其基本锁定变为可用,而是在这种情况下等待一些通知或超时。

根据the Python docs on threading.Condition.wait

wait(timeout=None)
    Wait until notified or until a timeout occurs...

当您在某个条件上调用notify时,实际上是在通知在该条件对象上调用wait的n个线程,它们一旦获取基本锁就可能会停止等待

可以从the Python docs on threading.Condition.notify

推论得出
notify(n=1)
    ...
    Note: an awakened thread does not actually return
    from its wait() call until it can reacquire the lock.
    Since notify() does not release the lock, its caller should.

现在,这是我对代码正在发生的事情的有根据的猜测:

  • 生产者将许多项目推入队列。
  • 消费者从队列中消费了许多物品。
  • 队列很快就变空了。
  • 将通知消费者wait(),它可能会继续消费(只要它可以获取基础锁)
  • 生产者将项目推入队列。
  • 生产者永远不会向notify()消费者表明它可以继续消费。
  • 队列很快就满了。
  • 通知生产者wait(),它可能会恢复生产(只要它可以获取基础锁)
  • 消费者正在等待生产者唤醒,生产者正在等待被消费者唤醒
  • 僵局!