Каково значение condition.notify() в поточном модуле python?

Поэтому я использую условие Python из модуля потоков:

from threading import Thread, Condition
condition = Condition()

У меня есть класс Producer (подкласс Thread), который, по существу, в цикле for добавляет элементы в очередь до тех пор, пока очередь не заполнится (т. Е. Не достигла определенной максимальной длины), и класс Consumer, который в цикле for выводит элементы, если очередь не пуста., В источнике, если очередь заполнена, у нас есть оператор condition.wait (), и аналогично в классе-потребителе, если очередь пуста, у нас есть условие condition.wait (). Если ни одно из этих условий не выполнено (очередь не заполнена и не пуста), каждый класс делает свое дело (добавляет элемент в очередь или извлекает элемент соответственно для Producer или Consumer), а затем перед освобождением условия (condition.release ()), у нас есть условие condition.notify (). Я прочитал из документации, что notify () пробуждает один из ожидающих потоков.

Мой вопрос сейчас в два раза:

  1. Что именно "просыпаться" означает для потока?
  2. Когда я удалил операторы notify () из обоих классов, моя программа работает нормально, за несколько итераций циклов for (т. Е. Производитель выталкивает элементы, а потребитель выталкивает элементы), а затем в какой-то момент производитель продолжает помещать элементы в очередь без потребителя работает, очередь заполняется, но потребитель никогда не запускается снова, и программа просто останавливается. Какое значение имеет метод notify (), который важен для работы этой программы.

Большое спасибо за вашу помощь:)

1 ответ

1) Он сигнализирует потоку, ожидающему снятия блокировки, он может продолжить выполнение.

2) Condition.notify(n) занимает до n потоки из внутренней очереди и звонки release на замках они ждут - тем самым разбудив их. Если внутренняя очередь пуста, проснуться некому, и notify звонок не имеет никакого эффекта. Вот почему с самого начала, удаление notify не имел никакого эффекта, но когда-то потребительские темы назывались waitНе было никого, кто бы разбудил их, и они ждали вечно.

TL;DR

  1. Пробуждение здесь можно рассматривать как пробуждение производителя или потребителя от сна И информирование их о том, что они могут вернуться к работе, как только их общий PPE (базовая блокировка) станет доступен.

  2. Потребитель увидел, когда очередь пуста, и пошел спать, ожидая, пока производитель разбудит его, когда он добавит в очередь.

    Но вы лишили производителя возможности разбудить потребителя.

    Продюсер увидел, когда очередь наполнилась, и пошел спать, ожидая, пока потребитель разбудит его, когда он берет из очереди.

    Но вы лишили потребителя возможности разбудить производителя.

    И теперь они оба спят.


Правильное обсуждение

Ключ к пониманию значения Condition.notify() заключается в осознании того, что когда ты wait()Используя условие, вы НЕ ждете, когда станет доступной его базовая блокировка, а, скорее, вы ждете какого-либо уведомления или тайм-аута для этого условия.

Согласно документам Python о threading.Condition.wait

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

Когда вы вызываете notify при условии, вы по сути информируете n потоков, которые вызвали waitна этом объекте условия, что они могут перестать ждать, как только они смогут получить базовую блокировку.

Это можно сделать из документации Python по 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()s, чтобы получить уведомление о том, что он может возобновить потребление (как только сможет получить базовую блокировку)
  • Производитель помещает элементы в очередь.
  • Продюсер никогда не добирается до notify() потребителю, что он может возобновить потребление.
  • Очередь скоро заполнится.
  • Режиссер wait()s, чтобы получить уведомление о том, что он может возобновить производство (как только сможет получить базовую блокировку)
  • Потребитель ждет, чтобы его разбудил Продюсер, а Продюсер ждет, чтобы его разбудил Потребитель.
  • Безвыходное положение!
Другие вопросы по тегам