python Очередь, SimpleQueue, task_done - PullRequest
0 голосов
/ 09 июля 2020
  1. Нужно ли мне звонить task_done(), когда я использую queue.Queue()?

  2. Если мне не нужен подсчет задач, следует ли мне использовать queue.SimpleQueue вместо этого (для лучшей производительности)? Я не уверен, что SimpleQueue потокобезопасен? потому что я вижу, что реализация put() не получает блокировку?

  3. По мере того, как я использую реализацию Queue(), если я не буду вызывать task_done (), есть счетчик который увеличивается, и поскольку моя программа работает долго, отказ от вызова task_done () вызовет некоторую утечку памяти? из-за слишком большого числа.

1 Ответ

0 голосов
/ 09 июля 2020
  1. Вам не нужно вызывать task_done(), если вы не используете функцию Queue.join().

Queue.join() блокируется до тех пор, пока все элементы в очереди не будут получены и обработано.

Счетчик незавершенных задач увеличивается всякий раз, когда элемент добавляется в очередь. Счетчик уменьшается всякий раз, когда потребительский поток вызывает task_done(), чтобы указать, что элемент был получен и вся работа над ним завершена. Когда количество незавершенных задач падает до нуля, join() разблокируется.

Да, вы можете использовать queue.SimpleQueue вместо queue.Queue как более легкую версию, если вам не нужна функция отслеживания (task_done, join). SimpleQueue является потокобезопасным и более того, поскольку ответил здесь

Он обрабатывает повторный вход - в нестандартных ситуациях, когда это может быть, безопасно звонить queue.SimpleQueue.put прерывание другой работы в том же потоке. Например, вы можете безопасно вызывать его из методов __del__, обратных вызовов weakref или обработчиков сигналов сигнального модуля.

Примечание: по крайней мере, это относится к его реализации C.

Насколько мне известно, queue.Queue использует int в качестве счетчика put. И, по моему скромному мнению, вероятность того, что этот счетчик будет занимать слишком много памяти, скорее теоретическая, чем практическая.
...