El límite máximo de tamaño de la cola de multiprocesamiento es 32767

Estoy tratando de escribir un progtwig Python 2.6 (OSX) usando multiprocesamiento, y quiero rellenar una Cola con más de la cantidad predeterminada de 32767 elementos.

from multiprocessing import Queue Queue(2**15) # raises OSError 

Queue(32767) funciona bien, pero cualquier número mayor (por ejemplo, Queue(32768) ) falla con OSError: [Errno 22] Invalid argument

¿Hay una solución para este problema?

Un enfoque sería envolver su multiprocessing.Queue . multiprocessing.Queue con una clase personalizada (solo en el lado del productor, o de manera transparente desde la perspectiva del consumidor). Usando eso, pondrías en cola los elementos que se enviarán al objeto Queue que estás envolviendo, y solo alimentarías cosas desde la cola local (objeto de Python list() ) al multiprocess.Queue medida que el espacio esté disponible, con un manejo excepcional del acelerador. cuando la Queue está llena

Ese es probablemente el enfoque más fácil, ya que debería tener el mínimo impacto en el rest de su código. La clase personalizada debe comportarse como una cola mientras oculta el multiprocessing.Queue subyacente. multiprocessing.Queue detrás de su abstracción.

(Un enfoque podría ser hacer que su productor use subprocesos, un subproceso para administrar el envío de una Queue subprocesos a su multiprocessing.Queue . La multiprocessing.Queue y cualquier otro subproceso en realidad solo alimenta la Queue subprocesos).

Ya he respondido a la pregunta original, pero siento que agregar que las listas de Redis son bastante confiables y que el soporte del módulo Python para ellas es extremadamente fácil de usar para implementar un objeto similar a la cola. Estos tienen la ventaja de permitir que uno se amplíe en varios nodos (a través de una red), así como en varios procesos.

Básicamente, para usar aquellos que solo escogería una clave (cadena) para el nombre de su cola, haga que sus productores los presionen y que sus trabajadores (consumidores de tareas) formen un bucle para bloquear los elementos emergentes de esa clave.

Los comandos Redis BLPOP y BRPOP toman una lista de claves (listas / colas) y un valor de tiempo de espera opcional. Devuelven una tupla (clave, valor) o Ninguna (en tiempo de espera). Así que puedes escribir fácilmente un sistema dirigido por eventos que sea muy similar a la estructura familiar de select () (pero a un nivel mucho más alto). Lo único que debe observar son las claves faltantes y los tipos de clave no válidos (por supuesto, envuelva las operaciones de la cola con controladores de excepciones). (Si alguna otra aplicación se detiene en su servidor Redis compartido, elimine las claves o reemplace las claves que estaba usando como colas con cadena / entero u otros tipos de valores … bueno, en ese momento tiene un problema diferente). 🙂

Otra ventaja de este modelo es que Redis conserva sus datos en el disco. Por lo tanto, su cola de trabajo podría sobrevivir a los reinicios del sistema si elige permitirlo.

(Por supuesto, podría implementar una cola simple como una tabla en SQLlite o en cualquier otro sistema SQL si realmente quisiera hacerlo; simplemente utilizando algún tipo de índice de incremento automático para la secuenciación y una columna para marcar cada elemento que haya sido ” hecho “(consumido); pero eso implica algo más de complejidad que usar lo que Redis le da” fuera de la caja “).

Trabajando para mi en MacOSX

 >>> import Queue >>> Queue.Queue(30000000)