Очередь многопроцессорной обработки Python, когда установлено значение бесконечность, ограничена 32768 (2 ^ 15)

У меня есть список примерно из 800000 элементов (небольших строк), которые загружаются в очередь, которая затем используется различными рабочими процессами из многопроцессорного пула. Я обнаружил, что как в PyPy, так и в Python (2.7 и 3.6 соответственно), хотя я явно установил максимальный размер очереди равным 0, очередь в обоих случаях ограничена 32768 элементами в любой момент времени и, следовательно, блокирует на 32768 элементе.

Почему это происходит? Я думал, что они должны быть бесконечными, если maxsize <= 0? Я рассмотрел этот вопрос StackOverflow Python Queue поднимает Full, даже если он бесконечен, но он единственный такого рода. Есть ли что-то еще, что я могу упустить?

Я пробовал реализации многопроцессорной очереди, где я загружаю миллион целых чисел, а метод queue.put(val) всегда блокируется на 32768-м значении.

from multiprocessing import Queue
q = Queue(maxsize=0)
for i in range(int(1e7)):
    q.put(i)
    print(i)

Я ожидал, что смогу вставить в очередь все 1 миллион целых чисел, но, как оказалось, она не может удержать их все, так как блокирует 32768-е целое число. Я хотел бы пролить свет на особенности того, почему это может происходить, на что, возможно, уже был дан ответ в другом вопросе StackOverflow, указанном выше, но похоже, что пользователь, давший ответ, спросил, используем ли мы 32-битный Дистрибутив Python, который не является моим случаем, так как я использую 64-битный дистрибутив Python в обоих случаях, как видно здесь (для PyPy с 2.7.13, который я использую в своем проекте):

Python 2.7.13 (990cef41fe11, Mar 21 2019, 12:15:10)
[PyPy 7.1.0 with GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>> import sys;print("%x" % sys.maxsize, sys.maxsize > 2**32)
('7fffffffffffffff', True)

ОБНОВИТЬ:

Я заметил кое-что очень интересное. Это произошло при запуске Queue в MacOS, но я запустил код в контейнере докеров с Linux, и очередь была эффективно загружена полностью со всеми 800000 элементами одновременно! Кажется, это как-то связано с MacOS.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
9
0
500
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Многопроцессорность Зависание очереди означает, что вы, скорее всего, превысили максимальное количество семафоров; то есть OSX не может считать так много и неявно ограничивает вас до 2 ^ 15 - 1.

Я не уверен, насколько надежен / актуален источник, но он соответствует, по-видимому, максимальному значению для osx (https://github.com/st3fan/osx-10.9/blob/master/xnu-2422.1.72/bsd/sys/semaphore.h)

Редактировать/проверить:

Явная попытка использовать большее ограничение, чем 2 ^ 15 - 1, терпит неудачу:

>>> Queue(maxsize=2**15)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/context.py", line 102, in Queue
    return Queue(maxsize, ctx=self.get_context())
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/queues.py", line 48, in __init__
    self._sem = ctx.BoundedSemaphore(maxsize)
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/context.py", line 87, in BoundedSemaphore
    return BoundedSemaphore(value, ctx=self.get_context())
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/synchronize.py", line 145, in __init__
    SemLock.__init__(self, SEMAPHORE, value, value, ctx=ctx)
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/synchronize.py", line 59, in __init__
    unlink_now)
OSError: [Errno 22] Invalid argument

В вашем случае вы пытались неявно создать очередь бесконечного размера (<=0), однако на самом деле это не так, и применяются ограничения OSX: https://github.com/python/cpython/blob/master/Lib/multiprocessing/queues.py#L37

То, чем вы делитесь, имеет большой смысл, но как это применимо к Linux? Кажется, нет проблем с загрузкой всех значений в очередь. Более того, означает ли это, что у каждого элемента в очереди есть семафор?

Juan Amari 30.05.2019 16:12

Я предполагаю, что предел Linux просто выше, что имеет смысл, поскольку предел OSX кажется очень низким. И нет, у вас есть только один семафор для всей очереди, однако он не может считать более 2 ^ 15 - 1 из-за ограничения OSX, поэтому он заблокирован до этого размера. вы можете увидеть это здесь: github.com/python/cpython/blob/master/Lib/multiprocessing/…

leongold 30.05.2019 16:49

Это имеет большой смысл, Леон, большое спасибо за разъяснение.

Juan Amari 30.05.2019 17:03

Другие вопросы по теме