Python 3: Будет ли корректно Queue.empty (), если в течение некоторого времени никакие потоки не вставляют или вытаскивают элементы? - PullRequest
0 голосов
/ 03 января 2019

Я использую 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(), верно?

1 Ответ

0 голосов
/ 03 января 2019

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

Метод Queue.empty() возвращает значение True или False в зависимости от текущего состояния очереди.Проблема заключается в том, что это состояние может измениться в любой момент, когда другой поток получает контроль и взаимодействует с очередью, то есть внутри одного потока, за исключением других примитивов синхронизации (блокировки, семафоры, события, условия, барьеры, что-у-вас-вы),Вы не можете полагаться на возвращаемое значение в течение любого отрезка времени.

Для этого существует нет таймфрейма , в котором вы можете рассчитывать на стабилизацию состояния.Не существует «нестабильного состояния» в объекте очереди, только в вашем приложении в целом, потому что вы используете потоки.

То же самое относится к методу Queue.qsize();возвращаемое значение не является нечетким или приблизительным, оно является точной мерой состояния очереди в тот момент времени .Но поскольку ваш код может и будет прерван при передаче управления другому потоку, вы не можете полагаться на это измерение, чтобы сообщить, как ваш код может затем действовать в очереди, потому что к моменту следующей инструкциив вашем потоке может повлиять на это измерение, управление, возможно, было переключено назад и обратно, другой поток мог бы действовать в очереди, и измерение больше не имеет значения.

Используйте другие примитивы синхронизации для связи между вашимтемы, если вам нужно что-то более определенное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...