2012-04-05 19 views
11

Estoy trabajando en un proyecto bastante grande en Python que requiere que una de las tareas de fondo con uso intensivo de cómputo sea descargada a otro núcleo, para que el servicio principal no se desacelere. Me he encontrado con un comportamiento aparentemente extraño al usar multiprocessing.Queue para comunicar los resultados del proceso de trabajo. Usando la misma cola tanto para threading.Thread como para multiprocessing.Process para fines de comparación, el hilo funciona bien pero el proceso no se puede unir después de colocar un artículo grande en la cola. Observo:Tamaño máximo para multiprocesamiento. ¿Qué artículo?

import threading 
import multiprocessing 

class WorkerThread(threading.Thread): 
    def __init__(self, queue, size): 
     threading.Thread.__init__(self) 
     self.queue = queue 
     self.size = size 

    def run(self): 
     self.queue.put(range(size)) 


class WorkerProcess(multiprocessing.Process): 
    def __init__(self, queue, size): 
     multiprocessing.Process.__init__(self) 
     self.queue = queue 
     self.size = size 

    def run(self): 
     self.queue.put(range(size)) 


if __name__ == "__main__": 
    size = 100000 
    queue = multiprocessing.Queue() 

    worker_t = WorkerThread(queue, size) 
    worker_p = WorkerProcess(queue, size) 

    worker_t.start() 
    worker_t.join() 
    print 'thread results length:', len(queue.get()) 

    worker_p.start() 
    worker_p.join() 
    print 'process results length:', len(queue.get()) 

que he visto que esto funciona bien para size = 10000, pero se cuelga en worker_p.join() para size = 100000. ¿Hay algún límite de tamaño inherente a lo que multiprocessing.Process instancias pueden poner en un multiprocessing.Queue? ¿O estoy cometiendo un error obvio y fundamental aquí?

Como referencia, estoy usando Python 2.6.5 en Ubuntu 10.04.

Respuesta

16

Parece que la tubería subyacente está llena, por lo que la rosca del alimentador bloquea la escritura en la tubería (en realidad cuando se intenta adquirir el bloqueo que protege la tubería del acceso concurrente).

Comprobar este problema http://bugs.python.org/issue8237

+2

Gracias, ese es exactamente el problema que estoy experimentando, y dequeuing en el hilo padre antes de unirse parece funcionar bien. –

+1

muchas gracias. simplemente cambie 2 líneas: "worker_t.join() print 'thread results length:', len (queue.get())" – Catbuilts

Cuestiones relacionadas