Найти - Пользователи
Полная версия: Queue
Начало » Python для новичков » Queue
1 2
bazooka
Проясните плиз кто знает.
В доке написано
Queue.empty()
Return True if the queue is empty, False otherwise. If empty() returns True it doesn’t guarantee that a subsequent call to put() will not block. Similarly, if empty() returns False it doesn’t guarantee that a subsequent call to get() will not block.
т.е там не гарантируется ниче, нафиг тогда этот метод? Можно ли им все-таки проверять незаполненость?

и там же в доке

def worker():
while True:
item = q.get()
do_work(item)
q.task_done()
т.е если не вызвать task_done то Queue может отдать тоже самое еще раз?
Lexander
bazooka
Не гарантируется блокировка очереди для get(), put(), которые будут идти следующими в коде.
Т.е. сам по себе вызов проверки наличия элементов в очереди ничего не блокирует и не резервирует место в очереди или первый элемент в очереди, что вполне логично. Блокировка происходит позднее, когда вызывается get(), put().

В любом случае, хотелось бы услышать какая стоит задача, которая предполагает, что в коде
if q.empty():
some_work_with_put()
else:
another_work_with_get()
после 1 строки вам нужно боятся переполнения очереди.
bazooka
пасиба, я въехал

была задача которая предполагала

if not q.empty():
some_work_with_get()
Lexander
bazooka
была задача которая предполагала
Разве система настолько была настолько нагружена, имела несколько независимых читателей очереди, что была возможность коллизии?
Это я к тому, что на самом деле существует не так уж много задач, которые требуют отдельной проработки операций с очередью.
ZZZ
bazooka
if not q.empty():
some_work_with_get()
Плохая идея. Лучше обрабатывать исключение Queue.Empty – по крайней мере это более логично и потокобезопасно.

Lexander
Разве система настолько была настолько нагружена, имела несколько независимых читателей очереди, что была возможность коллизии?
Это я к тому, что на самом деле существует не так уж много задач, которые требуют отдельной проработки операций с очередью.
Queue.Queue, это очень удобный инструмент. Да, иногда его использовать избыточно, но довольно часто это просто удобно.
Lexander
ZZZ
Queue.Queue, это очень удобный инструмент. Да, иногда его использовать избыточно, но довольно часто это просто удобно.
В моем предложении еще было слово “отдельной” и я не отговаривал (или удивлялся) от использования очереди ;)
ZZZ
Плохая идея. Лучше обрабатывать исключение Queue.Empty – по крайней мере это более логично и потокобезопасно.
У вас были проекты, в которых чтение из очереди производилось из разных потоков?
Лично у меня нет. Когда будут такие задачи, тогда и только тогда можно говорить о плохой идее. И даже больше - это реально просчет проектирования.

ЗЫ
Ничего что я так категорично? :) Это я в ответ на вашу категоричность о плохой идее. Ничего личного :)
ZZZ
Всё нормально. У меня такие задачи были. И не раз.

Есть четыре варианта, когда очередь жизненно необходима:
1. Несколько потоков добавляют в очередь данные и один поток берёт их по-одному для обработки;
2. Один поток пишет данные в очередь и несколько потоков берут эти данные для обработки;
3. Один к одному;
4. Много ко многому (в моей практике не встречалось).

Lexander
И даже больше - это реально просчет проектирования.
С чего это? Я очень люблю нити и постоянно их использую, и само собой, мне нужны средства для их синхронизации. Иногда это просто лок, иногда семафор… Но чаще всего именно очередь. И это удобно.
Lexander
ZZZ
Всё нормально. У меня такие задачи были. И не раз.

Есть четыре варианта, когда очередь жизненно необходима:
1. Несколько потоков добавляют в очередь данные и один поток берёт их по-одному для обработки;
2. Один поток пишет данные в очередь и несколько потоков берут эти данные для обработки;
3. Один к одному;
4. Много ко многому (в моей практике не встречалось).
Вот именно.
В случае когда вариант 2 или 4, который и требует наличие собственных блокировок (ну или обработки исключения Empty) - кому как нравится, код
if not q.empty():
some_work_with_get()
без обработки внутри some_work_with_get() исключения Empty - плохой код (и ошибка в проектировании) и здесь я с вами полностью согласен.

А когда вариант 1 и 3 - код вполне правильный, разве не так?
ZZZ
Он правильный тем, что будет работать, но не очень правильный с точки зрения стилистики. ИМХО.
Всё-таки операции get и put нужно обрамлять в try…except, чтобы потом, когда захочется добавить ещё поток, не поймать странных, трудноуловимых, глюков.
Lexander
ZZZ
Он правильный тем, что будет работать, но не очень правильный с точки зрения стилистики. ИМХО.
Всё-таки операции get и put нужно обрамлять в try…except, чтобы потом, когда захочется добавить ещё поток, не поймать странных, трудноуловимых, глюков.
Ну, в общем то ваша мысль понятна, хотя я не разделяю этой предусмотрительности “на вырост” при заранее известном ТЗ :)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB