¿Puedo usar una cola de multiprocesamiento en una función llamada por Pool.imap?

Estoy usando Python 2.7 y tratando de ejecutar algunas tareas pesadas de CPU en sus propios procesos. Me gustaría poder enviar mensajes al proceso principal para mantenerlo informado sobre el estado actual del proceso. La cola de multiprocesamiento parece perfecta para esto, pero no puedo averiguar cómo hacer que funcione.

Por lo tanto, este es mi ejemplo básico de trabajo, menos el uso de una cola.

import multiprocessing as mp import time def f(x): return x*x def main(): pool = mp.Pool() results = pool.imap_unordered(f, range(1, 6)) time.sleep(1) print str(results.next()) pool.close() pool.join() if __name__ == '__main__': main() 

He intentado pasar la cola de varias maneras y aparece el mensaje de error “RuntimeError: los objetos de la cola solo deben compartirse entre procesos a través de la herencia”. Esta es una de las formas en que lo intenté en base a una respuesta anterior que encontré. (Me sale el mismo problema al utilizar Pool.map_async y Pool.imap)

 import multiprocessing as mp import time def f(args): x = args[0] q = args[1] q.put(str(x)) time.sleep(0.1) return x*x def main(): q = mp.Queue() pool = mp.Pool() results = pool.imap_unordered(f, ([i, q] for i in range(1, 6))) print str(q.get()) pool.close() pool.join() if __name__ == '__main__': main() 

Finalmente, el enfoque de aptitud física 0 (hacerlo global) no genera ningún mensaje, simplemente se bloquea.

 import multiprocessing as mp import time q = mp.Queue() def f(x): q.put(str(x)) return x*x def main(): pool = mp.Pool() results = pool.imap_unordered(f, range(1, 6)) time.sleep(1) print q.get() pool.close() pool.join() if __name__ == '__main__': main() 

Soy consciente de que probablemente funcionará con multiprocesamiento. El proceso directamente y que existen otras bibliotecas para lograr esto, pero odio alejarme de las funciones de la biblioteca estándar, son una excelente opción hasta que estoy seguro de que no es solo mi falta del conocimiento que me impide poder explotarlos.

Gracias.

El truco es pasar la cola como un argumento al inicializador. Parece que funciona con todos los métodos de envío de Pool.

 import multiprocessing as mp def f(x): fqput('Doing: ' + str(x)) return x*x def f_init(q): fq = q def main(): jobs = range(1,6) q = mp.Queue() p = mp.Pool(None, f_init, [q]) results = p.imap(f, jobs) p.close() for i in range(len(jobs)): print q.get() print results.next() if __name__ == '__main__': main()