Я использую queue.Queue()
в Python 3.7 (Windows 10). Иногда мне нужно проверить, пуста очередь или нет. Документация гласит:
Queue.empty ()
Возврат True
, если очередь пуста, False
в противном случае. Если empty()
возвращает True
, это не гарантирует, что последующий вызов put()
не будет блокирован. Аналогичным образом, если empty()
возвращает значение False, это не гарантирует, что последующий вызов get()
не будет блокирован.
Другими словами, нельзя полностью полагаться на 100% возвращаемого значения из Queue.empty()
. Это кажется действительно естественным для меня. В многопоточной среде некоторые побочные потоки могут проникнуть и поместить элемент в очередь в тот самый момент, когда вы спрашиваете, пуста ли она. Следовательно, возвращенный ответ ненадежен. Я понял.
А как насчет следующего сценария? Таймер отсчитывает: t1
, t2
, t3
, ... На каждом такте таймера очередь спрашивает: «Вы пусты»?
t1 t2 t3 t4 t5 t6
---|--------|--------|--------|--------|--------|--------->
\__________ __________/\__________ ___________/
\/ \/
Different threads No action on
put elements on the the queue.
queue and/or pull
elements from it.
Теперь давайте представим, что начиная с отметки таймера t4
и далее, мы абсолютно уверены, что очередь не будет затронута каким-либо потоком - ни один элемент не будет вставлен, ни один не будет извлечен.
Возможно, при отметке таймера t4
очередь еще не успела внутренне стабилизироваться, и возвращаемое значение из Queue.empty()
неверно. Но стабилизируется ли он через некоторое время, скажем, по таймеру t5
или t6
?
Возможность 1: Нет, она никогда не стабилизируется
Это действительно ужасно. Я никогда не буду использовать эту очередь снова. Конец истории.
Возможность 2: Да, стабилизируется через x
миллисекунды
Я понимаю, что вы не можете дать точный ответ здесь. Это будет зависеть от многих факторов: операционной системы, аппаратного обеспечения, количества потоков, которые берут ресурсы, ... Но было бы здорово знать, что оно стабилизируется через некоторое время. Я просто возьму достаточно маржи.
Примечание:
Если Queue.empty()
стабилизируется (или нет) через некоторое время, я полагаю, то же самое верно для Queue.qsize()
, верно?