Problemas al mezclar hilos / procesos en python

Estoy empezando a intentar hacer cosas multiproceso / multiprocesador y me encuentro con algunos problemas. Lo que quiero hacer es generar una serie de solicitudes de datos que deben descargarse de una base de datos remota. Estos se almacenan en un Queue.Queue (llamémoslo in_q). Una vez que he generado todas las solicitudes, inicie un número limitado de mi clase de subproceso que toma in_q y otra Cola (out_q) como entrada. Luego obtengo () los trabajos de q_in y envío los resultados a q_out. Así que esta parte está vinculada a IO, por lo tanto, pensé que los hilos serían una buena opción. Los resultados de q_out son consumidos por un conjunto de procesos que realiza algunos trabajos en los procesos. Esta parte está vinculada a la CPU, por lo que pensé que los procesos serían una buena opción.

Ahora, esto parece funcionar bien, excepto que me he encontrado con un comportamiento extraño que he demostrado a continuación.

import threading import Queue import multiprocessing as mp class TestThread(threading.Thread): def __init__ ( self, threadnr,resultPool,jobPool ): self.threadnr = threadnr self.resultPool = resultPool self.jobPool = jobPool threading.Thread.__init__ ( self ) def run(self): while True: job = self.jobPool.get() if job != None: for a in range(10): for i in xrange(1000000): pass print "Thread nr %d finished job %d" % (self.threadnr,job) self.resultPool.put([self.threadnr,job+1]) self.jobPool.task_done() def test(i): print mp.current_process().name,"test",i return mp.current_process().name,"test",i if __name__ == '__main__': q_in = Queue.Queue() q_out = Queue.Queue() nr_jobs = 20 res = [] nr_threads = 4 threads = [] for i in range(nr_jobs): q_in.put(i) for i in range(nr_threads): t = TestThread(i,q_out,q_in) t.start() threads.append(t) p_pool = mp.Pool(4) for i in range(nr_jobs): job = q_out.get(block=True) print "Got job",job res.append(p_pool.apply_async(test,(job,))) p_pool.close() p_pool.join() for r in res: print r.get() for t in threads: t.join() 

La salida de esto es:

 Thread nr 2 finished job 2 Got job [2, 3] Thread nr 0 finished job 0 Got job [0, 1] Thread nr 1 finished job 1 Got job [1, 2] Thread nr 3 finished job 3 Got job [3, 4] Thread nr 2 finished job 4 Got job Thread nr 0 finished job 5[ 2, 5] Got job [0, 6] Thread nr 1 finished job 6 Got job [1, 7] Thread nr 3 finished job 7 Got job [3, 8] Thread nr 2 finished job 8 Got job [2, 9] Thread nr 0 finished job 9 Got job [0, 10] PoolWorker-4 test [1, 2] PoolWorker-4 test [1, 7] PoolWorker-3 test [3, 4] PoolWorker-3 test [3, 8] PoolWorker-2 test [0, 1] PoolWorker-2 test [0, 6] PoolWorker-2 test [0, 10] PoolWorker-1 test [2, 3] PoolWorker-1 test [2, 5] PoolWorker-1 test [2, 9] ('PoolWorker-1', 'test', [2, 3]) ('PoolWorker-2', 'test', [0, 1]) ('PoolWorker-4', 'test', [1, 2]) ('PoolWorker-3', 'test', [3, 4]) ('PoolWorker-1', 'test', [2, 5]) ('PoolWorker-2', 'test', [0, 6]) ('PoolWorker-4', 'test', [1, 7]) ('PoolWorker-3', 'test', [3, 8]) ('PoolWorker-1', 'test', [2, 9]) ('PoolWorker-2', 'test', [0, 10]) 

Es un progtwig de prueba que en términos generales funciona como mi progtwig real. Lo que me parece extraño es que a pesar de que los subprocesos tardan relativamente tiempo en finalizar los procesos, no se imprimen hasta que todos los subprocesos hayan hecho su trabajo. Parece que los trabajos se consumen continuamente, pero la salida de los procesos no aparece hasta después de que todos los subprocesos estén listos.

En este ejemplo, es bastante inofensivo (si es molesto), pero en mi progtwig real esto … la puesta en cola de la salida parece causar un error de memoria, ya que toda la salida de los procesos se retrasa hasta que finaliza el último hilo.

Y como una pregunta adicional, ¿es incluso una buena idea mezclar hilos y procesos o debería atenerme a uno u otro?

Apreciaría cualquier pensamiento al respecto.